Write a Q-SQL query to multiply the price of BA.N by 2, GS.N by 3 and MSFT.O by 4 and call the column newPrice using vector conditional statement - kdb

Write a Q-SQL query to multiply the price of BA.N by 2, GS.N by 3 and MSFT.O by 4 and call the column newPrice using vector conditional statement
tab2:`syms`prices!(`MSFT.O`GS.N`BA.N;45.15 191.10 178.50)
flip tab2
select syms,prices,newPrice:(prices*(4,3,2)) from flip tab2

I'm not sure using a vector conditional would be the easiest way to go about this. For example, you could use a simple dictionary to achieve a similar effect. First define a dictionary mapping your syms to their multipliers then use that dictionary in your select statement:
tab2: flip `syms`prices!(`MSFT.O`GS.N`BA.N;45.15 191.10 178.50)
d: `MSFT.O`GS.N`BA.N!4 3 2;
select syms, prices, newPrice: prices*d[syms] from tab2
syms prices newPrice
----------------------
MSFT.O 45.15 180.6
GS.N 191.1 573.3
BA.N 178.5 357
Vector conditionals can only return one of two results, depending on if the condition is true or false. To extend that limitation to what you want you could nest the conditionals inside each other. So like:
select syms, prices, newPrice: ?[syms=`MSFT.O; prices*4; ?[syms=`GS.N; prices*3; ?[syms=`BA.N;prices*2;prices]]] from tab2
But this quickly becomes unwieldy and doesn't scale well. If you added more syms, it would be easy to update the dictionary, but annoying to update the conditional.

You should create multipliers map
(`MSFT.O`GS.N`BA.N!2 3 4)
and multiply each price on value from the map based on row syms:
update newPrice: prices*(`MSFT.O`GS.N`BA.N!2 3 4)syms from flip tab2

Related

MATLAB drop observations from a timetable not contained in another timetable

I have two timetables, each of them have 4 columns, where the first 2 columns are of my particular interest. The first column is a date and the second is an hour.
How can I know which observations (by date an hour) are in the timetable 1 but not in the timetable 2 and, therefore, drop those observations from my timetable 1?
So for example, just by looking I realized that timetable1 included the day 25/05/2015 with hours 1 and 2, but the timetable 2 did not include them, therefore I would like to drop those observations from timetable 1.
I tried using the command groups_timetable1 = findgroups(timetable1.Date,timetable1.Hour);but unfortunately this command does not tell you a lot how to distinguish between observations.
Thank you!
call ismember to find one set of data in another.
to find multiple records as a group in another composite records, you call ismember(..., 'rows').
for example
baseline=[
100, 2.1
200, 7.5
120, 11.0
];
isin=ismember(baseline,[200, 7.5],'rows');
pos=find(isin)
if you have time date strings or datetime objects, please convert those to numerical values, such as by calling datenum or posixtime first.
You can use the timetable method innerjoin to do this. Like so:
% Fabricate some data
dates1 = datetime(2015, 5, ones(10,1));
hours1 = (1:10)';
timetable1 = timetable(dates1(:), hours1, rand(10,1), rand(10,1), ...
'VariableNames', {'Hour', 'Price', 'Volume'});
% Subselect a few rows for timetable2
timetable2 = timetable1([1:3, 6:10],:);
% Use innerjoin to pick rows where Time & Hour intersect:
innerjoin(timetable1, timetable2, 'Keys', {'Time', 'Hour'})
By default, the result of innerjoin contains the table variables from both input tables - that may or may not be what you want.

Iterate over columns with a fixed row

is it possible to iterate over columns with a fixed row/cell and to create a new column with the values. For example I want to create a column like that:
F1=A1
F2=B1
F3=C1
F4=D1
and so on
Write the formula
=MAX(OFFSET($A$1:$A$10000;0;ROW()-1))
in cell F1 and stretch it down.
The expression ROW()-1 will take the value 0 for F1, 1 for F2, 2 for F3, and so on, and the OFFSET() function uses these values ​​to move from the range A1:A10000 to 0, 1, 2, and so on columns.

KDB: select and round off each row

I created my own function of round off:
.q.rnd:{$[x < 0; -1; 1] * floor abs[x] + 0.5}
I have a table Test with a string column of COL
select "F"$(COL) from Test
24549.18741328
48939.50717263
-274853.33568872
-24549.18741328
298753.62574861
84822.70074144
-7468840.64371524
117944.21228603
-117944.21228603
7468840.64371524
-7468840.64371524
I want to derive a table that would round-off the records in Test
One would think that the statement below would work. But it does not.
select .q.rnd "F"$(COL) from Test
I get the error "type". So how do I round off the records?
The result if the if-else conditional must be an atomic boolean. When you run .q.rnd on a column, you are operating on a list and x<0 is going to return a list of booleans, not an atom. The vector conditional is ?
Nonetheless, it looks like you want a resulting integer/long anyway, so just use parse here
q)t:([]string (10?-1 1)*10?10000f)
q)select "F"$x from t
x
-------------------
4123.1701336801052
-9877.8444156050682
-3867.3530425876379
7267.8099689073861
4046.5459413826466
-8355.0649625249207
6427.3701561614871
-5830.2619284950197
1424.9352994374931
-9149.8820902779698
q)select "j"$"F"$x from t
x
-----
4123
-9878
-3867
7268
4047
-8355
6427
-5830
1425
-9150
To add to what Sean's said, if you wanted to use your function as well you could use each which will apply .q.rnd to each item in the list.
q)select .q.rnd each "F"$x from t
x
-----
-3928
5171
5160
-4067
-1781
3018
-7850
5347
-7112
-4116
but using select "F"$x from t is better as it is vectorised.
q)\t:1000 select "j"$"F"$x from t
22
q)\t:1000 select .q.rnd each "F"$x from t
33
Also it should be noted that the .q namespace isn't necessary and is "reserved for kx use". A lot of the default q functions are in the .q namespace and there's always a chance future kdb updates could add a .q.rnd that has different behaviour and will break any code where you have used your function in.

How to add values to last column of a table based on certain conditions in MATLAB?

I have a 29736 x 6 table, which is referred to as table_fault_test_data. It has 6 columns, with names wind_direction, wind_speed, air_temperature, air_pressure, density_hubheight and Fault_Condition respectively. What I want to do is to label the data in the Fault_Condition (last table column with either a 1 or a 0 value, depending on the values in the other columns.
I would like to do the following checks (For eg.)
If wind_direction value(column_1) is below 0.0040 and above 359.9940, label 6 th column entry corresponding to the respective row of the table as a 1, else label as 0.
Do this for the entire table. Similarly, do this check for others
like air_temperature, air_pressure and so on. I know that if-else
will be used for these checks. But, I am really confused as to how I
can do this for the whole table and add the corresponding value to
the 6 th column (Maybe using a loop or something).
Any help in this
regard would be highly appreciated. Many Thanks!
EDIT:
Further clarification: I have a 29736 x 6 table named table_fault_test_data . I want to add values to the 6 th column of table based on conditions as below:-
for i = 1:29736 % Iterating over the whole table row by row
if(1st column value <x | 1st column value > y)
% Add 0 to the Corresponding element of 6 th column i.e. table_fault_test_data(i,6)
elseif (2nd column value <x | 2nd column value > y)
% Add 0 to the Corresponding element of 6 th column i.e. table_fault_test_data(i,6)
elseif ... do this for other cases as well
else
% Add 1 to the Corresponding element of 6 th column i.e. table_fault_test_data(i,6)
This is the essence of my requirements. I hope this helps in understanding the question better.
You can use logical indexing, which is supported also for tables (for loops should be avoided, if possible). For example, suppose you want to implement the first condition, and also suppose your x and y are known; also, let us assume your table is called t
logicalIndecesFirstCondition = t{:,1} < x | t{:,2} >y
and then you could refer to the rows which verify this condition using logical indexing (please refer to logical indexing
E.g.:
t{logicalIndecesFirstCondition , 6} = t{logicalIndecesFirstCondition , 6} + 1.0;
This would add 1.0 to the 6th column, for the rows for which the logical condition is true

Postgis using contains and count even if answer is 0

I have a problem with the count function...
I want to isolate all polygons laying beside G10 polygon and I want to count number of points (subway stations) in my polygons (neighborhoods) but i want to receive an answer even if that answer must be 0.
I used the following statement :
select a2.name, count(m.geom)
from arr a1, arr a2, metro m
where n1.code='G10'
and ((st_touches(a1.geom, a2.geom)) or
(st_overlaps(a1.geom, a2.geom)))
and ST_Contains(a2.geom, s.geom)
group by a2.name, m.geom
I know the problem lies with the and ST_Contains(a2.geom, s.geom) part of the where clause, but I do not now how to solve it!
Use an explicit LEFT JOIN:
SELECT a1.name, COUNT(a2.code)
FROM arr a1
LEFT JOIN
arr a2
ON ST_Intersects(a1.geom, a2.geom)
WHERE a1.code = 'G10'
I'm not including the other tables as you have obvious typos in your original query and it's not clear how should they be connected