Hi,
how can I use the new Where function with lists of lists or matrices?
xs = {10, 20, 30, 50}; Where( Print(xs); xs ==10 ); xs = {[10 20], [30 50]}; Where( Print(xs); xs ==[10 20] );
on the first one
xs = {10, 20, 30, 50}; v=Where( xs ==10 ); print(v);
I am not sure of the second one
The first one was meant as working example
Print inside Where:to show that xs indeed refers to each individual element during the loop.[wow! - but explains the easy syntax]
"refers to each individual element"
... actually like in the second example.
Which makes me wonder about the second result - xs is [10 20], but Where doesn't find the match.
If you were to add one more item to your list, Where will break. I cannot really understand the error message
Not all sequences are the same size in access or evaluation of 'Where' , Bad Argument( Print(xs); xs == [10 20]; ), Where/*###*/(Print(xs) ; xs == [10 20])
Names Default To Here(1); xs = {[10 20], [30 50], [10 20]}; Where( Print(xs); xs == [10 20]; );
Other example in the Scripting Index seems to be closest to this, but using index 1 doesn't really work in this case.
@EvanMcCorkle
If you make a simple comparison like
Names Default To Here(1); xs = {[10 20], [30 50], [10 20]}; mask = Repeat(Eval List({[10 20]}), N Items(xs)); xs[1] == mask[1];
you won't get back 1, you will get back [1 1] (so one for each match). You should be able to convert this to 1 using All, but Where doesn't like that either (it seems to only compare first item in the matrix?)
Names Default To Here(1); xs = {[10 20], [30 20]}; Where(Show(xs == [10 20])); // [1 0] and [0 1]
If you try with xs[1], it will work until you add third item (or remove one) so most likely it is comparing wrong thing
Names Default To Here(1); xs = {[10 20], [30 20]}; r = Where( Show(xs[1] == [10 20]); xs[1] == [10 20]; );
Finally with a lot of trial, error and guess work this worked at least from time to time (not really sure if you want to create large matrices for a mask). This isn't what you would expect from Where() to be for this type of comparisons unless it is documented properly
</CODE></PRE> <P>Also doing it this way seems to be slower than just using Loc() but my test might be flawed</P> <div class="lia-spoiler-container"><a class="lia-spoiler-link" href="#" rel="nofollow noopener noreferrer">View more...</a><noscript> (Highlight to read)</noscript><div class="lia-spoiler-border"><div class="lia-spoiler-content"> <PRE><CODE class=" language-jsl">Names Default To Here(1); testitems = 300; //xs = {[10 20], [30 20], [10 20]}; xs = Repeat({[10 20]}, testitems / 3); xs = xs || Repeat({[30 20]}, testitems / 3); xs = xs || Repeat({[1 2]}, testitems / 3); xs = xs[Random Shuffle(1::testitems)]; testcount = 10000; where_speed = Repeat({.}, testcount); loc_speed = Repeat({.}, testcount); matches = Repeat({.}, testcount); category = Repeat({""}, testcount); expr1 = Expr( wait(0); a = HP Time(); mask = Repeat(Eval List({[10 20]}), N Items(xs)); r1 = Where(All(xs == mask)); wait(0); b = HP Time(); ); expr2 = Expr( wait(0); c = HP Time(); r2 = Loc(xs, [10 20]); wait(0); d = HP Time(); ); For(i = 1, i <= testcount, i++, wait(0); If(Random Integer(1, 2) == 2, expr2; expr1; cur_cat = "Loc"; , expr1; expr2; cur_cat = "Where"; ); where_speed[i] = b - a; loc_speed[i] = d - c; category[i] = "Loc"; matches[i] = Try(All(r1 == r2), 0); wait(0); ); dt = New Table("Test", Add Rows(testcount), New Column("Row", Numeric, Ordinal, Formula(Row())), New Column("Locs", Numeric, Continuous, Values(loc_speed)), New Column("Where", Numeric, Continuous, Values(where_speed)), New Column("Matches", Numeric, Nominal, Values(matches)), New Column("Category", Character, Nominal, Values(category)) ); tab = dt << Tabulate( Show Control Panel(0), Add Table( Column Table(Analysis Columns(:Locs, :Where)), Row Table( Grouping Columns(:Category), Statistics(Mean, Median, Std Dev, Interquartile Range) ) ) );Names Default To Here(1); xs = {[10 20], [30 20], [10 20]}; mask = Repeat(Eval List({[10 20]}), N Items(xs)); r = Where( //show(xs, mask, xs == mask, All(xs == mask)); All(xs == mask); );
</CODE></PRE> <P>Also doing it this way seems to be slower than just using Loc() but my test might be flawed</P> <div class="lia-spoiler-container"><a class="lia-spoiler-link" href="#" rel="nofollow noopener noreferrer">View more...</a><noscript> (Highlight to read)</noscript><div class="lia-spoiler-border"><div class="lia-spoiler-content"> <PRE><CODE class=" language-jsl">Names Default To Here(1); testitems = 300; //xs = {[10 20], [30 20], [10 20]}; xs = Repeat({[10 20]}, testitems / 3); xs = xs || Repeat({[30 20]}, testitems / 3); xs = xs || Repeat({[1 2]}, testitems / 3); xs = xs[Random Shuffle(1::testitems)]; testcount = 10000; where_speed = Repeat({.}, testcount); loc_speed = Repeat({.}, testcount); matches = Repeat({.}, testcount); category = Repeat({""}, testcount); expr1 = Expr( wait(0); a = HP Time(); mask = Repeat(Eval List({[10 20]}), N Items(xs)); r1 = Where(All(xs == mask)); wait(0); b = HP Time(); ); expr2 = Expr( wait(0); c = HP Time(); r2 = Loc(xs, [10 20]); wait(0); d = HP Time(); ); For(i = 1, i <= testcount, i++, wait(0); If(Random Integer(1, 2) == 2, expr2; expr1; cur_cat = "Loc"; , expr1; expr2; cur_cat = "Where"; ); where_speed[i] = b - a; loc_speed[i] = d - c; category[i] = "Loc"; matches[i] = Try(All(r1 == r2), 0); wait(0); ); dt = New Table("Test", Add Rows(testcount), New Column("Row", Numeric, Ordinal, Formula(Row())), New Column("Locs", Numeric, Continuous, Values(loc_speed)), New Column("Where", Numeric, Continuous, Values(where_speed)), New Column("Matches", Numeric, Nominal, Values(matches)), New Column("Category", Character, Nominal, Values(category)) ); tab = dt << Tabulate( Show Control Panel(0), Add Table( Column Table(Analysis Columns(:Locs, :Where)), Row Table( Grouping Columns(:Category), Statistics(Mean, Median, Std Dev, Interquartile Range) ) ) );
Thanks for the insights and the trick via Mask - much faster than
Where( xs[0,1] ==10 & xs[0,2] ==20 );
... but no chance to beat Loc.
kind of surprising ...