I have a table
t: flip `S`V ! ((`$"|A|B|"; `$"|B|C|D|"; `$"|B|"); 1 2 3)
and some dicts
t1: 4 10 15 20 ! 1 2 3 5;
t2: 4 10 15 20 ! 0.5 2 4 5;
Now I need to add a column with values on the the substrings in S and the function below (which is a bit pseudocode because I am stuck here).
f:{[s;v];
if[`A in "|" vs string s; t:t1;];
else if[`B in "|" vs string s; t:t2;];
k: asc key t;
:t k k binr v;
}
problems are that s and v are passed in as full column vectors when I do something like
update l:f[S,V] from t;
How can I make this an operation that works by row?
How can I make this a vectorized function?
Thanks
You will want to use the each-both adverb to apply a function over two columns by row.
In your case:
update l:f'[S;V] from t;
To help with your pseudocode function, you might want to use $, the if-else operator, e.g.
f:{[s;v]
t:$["A"in ls:"|"vs string s;t1;"B"in ls;t2;()!()];
k:asc key t;
:t k k binr v;
};
You've not mentioned a final else clause in your pseudocode but $ expects one hence the empty dictionary at the end.
Also note that in your table the columns S and V have been cast to a symbol. vs expects a string to split so I've had to use the stringoperation - this could be removed if you are able to redefine your original table.
Hope this helps!
Related
Why does sum work here, but the underlying form +/ not work? (Taken from https://code.kx.com/q/ref/sum/)
t: ([]name:`Jack`Jill`Janet;hair:`brown`black`fair;eye:`blue`green`hazel;age:12 9 14)
q)select sum age from t
age
---
35
q)select +/age from j
'/
[0] select +/age from j
^
This is because +/ is k syntax. To invoke it (and similar k constructs) in q you will need to wrap it in parentheses.
select enlist (+/)age from j
In general, if an inbuilt q keyword exists for the associated k expression, you should use the keyword (sum in this case) as it likely carries further optimisations.
In the case of sum q will automatically enlist the result inside a select statement which (+/) won't do. Hence why I have done it manually above. Otherwise expect a 'rank error.
I have the following
mydata:raze {[x]
L: select from ....
if[count[L] <= 20; continue]
} peach vals;
and I am trying to add an if-statement that would skip a particular entry in vals if the condition is not met. continueworks well in matlab, but, I am not sure of the corresponding syntax in kdb. Thank you.
You can use an explicit return (:) in the if statement to return an empty list for those cases. Something like:
mydata:raze {[x]
L: select from ....
if[count[L] <= 20; :()]
} peach vals;
I have a simple function which returns a table:
F[("A";"B");(1,-1)]
I would like to apply this function passing vectors as inputs:
a:((`A;`B);(`B;`C);(`C;`D))
b:((1;-1);(1;-1);(1;-1))
I have tried:
F each a,b
F each a cross b
but this doesn't work or combines the vectors rather than keeping the 2 components separate. In addition when I do get it to work how do I row bind the resulting list of tables? I am coming from a python background.
You need to use ' each-both :
q)F:{ ([] enlist x; enlist y)} /if F is simply creating a table
q)F[("A";"B");(1,-1)]
x y
---------
"AB" 1 -1
q)a:((`A;`B);(`B;`C);(`C;`D))
q)b:((1;-1);(1;-1);(1;-1))
q)F'[a;b] /each-both
+`x`y!(,`A`B;,1 -1)
+`x`y!(,`B`C;,1 -1)
+`x`y!(,`C`D;,1 -1)
raze will format it to a table (i think row binding means appending the tables together)
q)raze F'[a;b]
x y
--------
A B 1 -1
B C 1 -1
C D 1 -1
How do i passed 2 variables to a lambda function, where x is a number and y is a symbol.
I have written this, but it wouldn't process
{[x;y]
// some calculation with x and y
}
each ((til 5) ,\:/: `a`b`c`d`f)
It seems to be complaining that i am missing another arg.
Here's an example that I think does what you're looking for:
q){string[x],string y}./: raze (til 5) ,\:/: `a`b`c`d`f
The issue with your example is that you need to raze the output of ((til 5) ,\:/: `a`b`c`d`f) to get your list of 2 inputs.
Passing a list of variables into a function is accomplished using "." (dot apply) http://code.kx.com/q/ref/unclassified/#apply
.e.g
q){x+y} . 10 2
12
In my example, I've then used an "each right" to then apply to each pair. http://code.kx.com/q/ref/adverbs/#each-right
Alternatively, you could use the each instead if you wrapped the function in another lamda
q){{string[x],string y} . x} each raze (til 5) ,\:/: `a`b`c`d`f
Instead of generating a list of arguments using cross or ",/:\:" and passing each of these into your function, modify your function with each left each right ("/:\:") to give you all combination. his should take the format;
x f/:\: y
Where x and y are both lists. Reusing the example {string[x],string y};
til[5] {string[x], string y}/:\:`a`b`c`d
This will give you a matrix of all combinations of x and y. If you want to flatten that list add a 'raze'
Cause I've tried doing the truth table unfortunately one has 3 literals and the other has 4 so i got confused.
F = (A+B+C)(A+B+D')+B'C;
and this is the simplified version
F = A + B + C
http://www.belley.org/etc141/Boolean%20Sinplification%20Exercises/Boolean%20Simplification%20Exercise%20Questions.pdf
cause I think there's something wrong with this reviewer.. or is it accurate?
btw is simplification different from minimizing from Sum of Minterms to Sum of Products?
Yes, it is the same.
Draw the truth table for both expressions, assuming that there are four input variables in both. The value of D will not play into the second truth table: values in cells with D=1 will match values in cells with D=0. In other words, you can think of the second expression as
F = A +B + C + (0)(D)
You will see that both tables match: the (A+B+C)(A+B+D') subexpression has zeros in ABCD= {0000, 0001, 0011}; (A+B+C) has zeros only at {0000, 0001}. Adding B'C patches zero at 0011 in the first subexpressions, so the results are equivalent.