kdb how to aj with the first time of appearance - kdb

Here is my problem:
I have two tables:
q)t1:([]sym:1 5;x: 90 90)
q)t2:([]sym: 2 3 4 6 7 8; y: 100 200 300 400 500 600)
If I do aj[`sym;t2;t1], all the 6 columns in the result table will contain x with value 90.
But what I want is value 90 in column x only in row with sym 2 and 6, i.e the first time that sym in table t2 appear before table t1.
In other words, I want the result table to be like this:
q)([]sym:2 3 4 6 7 8; y: 100 200 300 400 500 600; x:90 0N 0N 90 0N 0N)
sym y x
----------
2 100 90
3 200
4 300
6 400 90
7 500
8 600
Could anyone tell me how I can achieve this? Thank you so much!

Not sure if aj can be used in this sense. This might give you what you need:
q)t2 lj 1!update sym:{x x binr y}[t2.sym;sym] from t1
sym y x
----------
2 100 90
3 200
4 300
6 400 90
7 500
8 600
Uses binr to find the next value greater than the value in t1 then joins only on that.
EDIT: note also that binr is >= ..... If you need strictly greater than you could use:
q)t2 lj 1!update sym:{x 1+x bin y}[t2.sym;sym] from t1
sym y x
----------
2 100 90
3 200
5 300
6 400 90
7 500
8 600

You can do aj to get the index where nearest smaller number of x will fit in, then a vector condition to get x when that index has got incremented, i.e.
select sym, y, x:?[c>prev c;x;0n] from aj[`sym; t2; update c:i from t1]

Related

Reshape array in octave / matlab

I'm trying to reshape an array but I'm having some issues.
I have an array see image below and I'm trying to get it to look like / follow the pattern in the row highlighted in yellow. (note: I'm not trying to calculate the array but reshape it so it follows a pattern)
aa=[1:5;10:10:50;100:100:500]
aa_new=reshape(aa',[1 numel(aa)])
aa_new produces:
1 2 3 4 5 10 20 30 40 50 100 200 300 400 500
I'm trying to get:
1 2 3 4 5 50 40 30 20 10 100 200 300 400 500
Reverse the column numbers of every second row i.e.
aa(2:2:end,:) = aa(2:2:end, end:-1:1);
Now you're good to go with reshaping:
aa = reshape(aa.', 1, []);

kdb voolkup. get value from table that is mapped to smallest val larger than x

Assuming I have a dict
d:flip(100 200 400 800 1600; 1 3 4 6 10)
how can I create a lookup function that returns the value of the smallest key that is larger than x? Given a table
tbl:flip `sym`val!(`a`b`c`d; 50 280 1200 1800)
I would like to do something like
{[x] : update new:fun[x[`val]] from x} each tbl
to end up at a table like this
tbl:flip `sym`val`new!(`a`b`c`d; 50 280 1200 1800; 1 4 10 0N)
sym val new
a 50 1
b 280 4
c 1200 10
d 1800
stepped dictionaries may help
http://code.kx.com/q/cookbook/temporal-data/#stepped-attribute
q)d:`s#-0W 100 200 400 800 1600!1 3 4 6 10 0N
q)d 50 280 1200 1800
1 4 10 0N
I think you will want to use binr to return the next element greater than or equal to x. Note that you should use a sorted list for this to work correctly. For the examples above, converting d to a dictionary with d:(!). flip d I came up with:
q)k:asc key d
q)d k k binr tbl`val
1 4 10 0N
q)update new:d k k binr val from tbl
sym val new
------------
a 50 1
b 280 4
c 1200 10
d 1800
Where you get the dictionary keys to use with: k k binr tbl`val.
Edit: if the value in the table needs to be mapped to a value greater than x but not equal to, you could try:
q)show tbl:update val:100 from tbl where i=0
sym val
--------
a 100
b 280
c 1200
d 1800
q)update new:d k (k-1) binr val from tbl
sym val new
------------
a 100 3
b 280 4
c 1200 10
d 1800

kdb update multiple columns corresponding to multiple where clauses

I have a table, which is :
t:([]a:1 3 2 1 2 3 3 2 1;b:10 20 30 40 50 60 70 80 90;c:100 200 300 400 500 600 700 800 900)
And I want all c to be 0 where a is equal to 2, and all be to be 0 where a is equal to 1.
Currently I have these two codes:
t:update b:0 from t where a=1
t:update c:0 from t where a=2
My question is how to combine these two lines of codes into one. Because I am working on a table which is far bigger than this simple example and it will take me a lot of rows of codes to do all the updates, which is too long.
You can use vector conditional for this:
update b:?[a=1;0;b], c:?[a=2;0;c] from t

Multiply each value in rows of Matrix A by each corresponding value of a specfic row in Matrix B

I have a A=[m,n] matrix and a B=[n,l] matrix.
A =
[1 2 3
4 5 6
7 8 9
10 11 12]
For the sake of simplicity, let's assume l=1, so B is in fact a vector B=[n,1]
B = [100 10 1]
I would like multiply all the values in each row of A by a corresponding value of B - column-wise.
I know how to do it "manually":
C=[A(:,1)*B(:,1), A(:,2)*B(:,2), A(:,3)*B(:,3)]
This is the result I want:
C = [100 20 3
400 50 6
700 80 9
1000 110 12]
Unfortunately my real life matrices are a bit bigger e.g. (D=[888,1270]) so I'm looking for smarter/faster way to do this.
Pre R2016b:
C=bsxfun(#times,A,B)
C =
100 20 3
400 50 6
700 80 9
1000 110 12
R2016b and later:
In MATLABĀ® R2016b and later, you can directly use operators instead of bsxfun , since the operators independently support implicit expansion of arrays.
C = A .* B
If I > 1, then you will have to reorder the dimensions of B first with a permute,
>> B = [100 10 1; 1 10 100];
>> C = bsxfun(#times, A, permute(B, [3 2 1]));
>> C
C(:,:,1) =
100 20 3
400 50 6
700 80 9
1000 110 12
C(:,:,2) =
1 20 300
4 50 600
7 80 900
10 110 1200

How can I divide each row of a matrix by a fixed row?

Suppose I have a matrix like:
100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60
...
I wish to divide each row by the second row (each element by the corresponding element), so I'll get:
100 100 100 100 100 100
1 1 1 1 1 1
10 10 10 10 10 10
...
Hw can I do it (without writing an explicit loop)?
Use bsxfun:
outMat = bsxfun (#rdivide, inMat, inMat(2,:));
The 1st argument to bsxfun is a handle to the function you want to apply, in this case right-division.
Here's a couple more equivalent ways:
M = [100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60];
%# BSXFUN
MM = bsxfun(#rdivide, M, M(2,:));
%# REPMAT
MM = M ./ repmat(M(2,:),size(M,1),1);
%# repetition by multiplication
MM = M ./ ( ones(size(M,1),1)*M(2,:) );
%# FOR-loop
MM = zeros(size(M));
for i=1:size(M,1)
MM(i,:) = M(i,:) ./ M(2,:);
end
The best solution is the one using BSXFUN (as posted by #Itamar Katz)
You can now use array vs matrix operations.
This will do the trick :
mat = [100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60];
result = mat ./ mat(2,:)
which will output :
result =
100 100 100 100 100 100
1 1 1 1 1 1
10 10 10 10 10 10
This will work in Octave and Matlab since R2016b.