Get minimum of a object - livescript

Firstly, good morning.
PreludeLS is able to get the minimum value of an array:
[1 2 3 4 5 6 7 8 9 10] |> minimum #=> 1
Now I figure out a way to get the minimum-by a unknown key. Let's suppose I have an object called A and it has 3 properties with 3 float values:
A =
A: 3.2
B: 4.2
C: 4.7
And I want to return the KeyValuePair of the element with a lower value:
{A: 32}
I can get the minimum by several objects by these objects having an equal index. How can I get the minimum by a unknown key?
Yeah, I've already read 3 times LiveScript's documentation and 2 times PreludeLS documentation

A |> obj-to-pairs |> minimum-by (.1)
#=> ['A', 3.2]
A |> obj-to-pairs |> minimum-by (.1) |> -> {(it.0): it.1}
#=> {A: 3.2}

Related

(KeyError): MultiIndex Slicing requires the index to be fully lexsorted tuple ... Why is this caused by a list, but not by a tuple?

This question is partially here to help me understand what lex-sorting is in the context of multi-indexes.
Say I have some MultiIndexed DataFrame df, and for the index I want to use:
a = (1, 1, 1)
So to pull the value from the dataframe I write:
df.loc[a, df.columns[i]]
Which works. But the following doesn't:
df.loc[list(a), df.columns[i]]
Giving me the error:
*** KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (1), lexsort depth (0)'
Why is this?
Also, another question, what does the following performance warning mean?
PerformanceWarning: indexing past lexsort depth may impact performance.
I'll illustrate the difference between passing a tuple and a list to .loc, using the example with df being
0 1 2
first second
bar one 4 4 7
two 3 4 7
foo one 8 1 8
two 7 5 4
Here df.loc[('foo', 'two')] returns the row indexed by this tuple, namely (7, 5, 4). The parameter specifies both levels of the multiindex.
But df.loc[['foo', 'two']] means you want all rows with the top level of the multiindex being either 'foo' or 'two'. A list means these are the options you want, and since only one level is provided in each option, the selection is based on the first (leftmost) level. The result:
0 1 2
first second
foo one 8 1 8
two 7 5 4
(Since there are no multiindices that begin with 'two', only those with 'foo' are present.)
Without seeing your dataframe, I can't tell where this difference leads to getting KeyError, but I hope the difference itself is clear now.

Array Numpy Side Effect

I found a strange effect when permuting array with numpy:
def permute(yy, kmax) :
kmax=5
kk= np.random.uniform(1,kmax)
nn= int(np.floor(len(yy)/kk))
yy3= np.zeros_like(yy );
np.copyto(yy3,yy)
for ii in range(0, nn):
ax= kk*ii-kk*nn
aux= yy[ax]
aux2= yy[kk*ii]
yy3[ax] = aux
yy3[kk*ii] = aux2
return yy3
and
yy= np.random.normal(0,1,50000)
yy1= permute(yy,2)
( np.var(yy)- np.var(yy1) )
( np.mean(yy)- np.mean(yy1) )
Result is not zero !!!
Do you think this comes from reference assignment in the array ?
I ran your function with np.arange(10) and got
1752:~/mypy$ python stack35004877.py
0.0
0.0
[0 1 2 3 4 5 6 7 8 9] # yy
[0 1 2 3 4 5 6 7 8 9] # yy1
And repeated it with the large random array, with the same 0s for the statistics.
Note that your code did not permute the input
Maybe it will be clearer if I clean it up:
def permute(yy, kmax=5) :
kk= np.random.randint(1,kmax) # int rather than float
nn= int(np.floor(len(yy)/kk))
print(nn,kk)
yy3= yy.copy()
for ii in range(0, nn):
ind1 = kk*ii
ind2 = ind1-kk*nn
yy3[ind2] = yy[ind2]
yy3[ind1] = yy[ind1]
return yy3
You aren't moving anything; and with kmax=2 you just copy every thing from yy to yy3 - something you already did outside the loop. With kmax=5 you don't copy everything in the loop - but the initial copy hides that.
With random.uniform(), kk is a float, and the indexes are also floats. That's not desirable, but apparently not a problem.
But even if I switch the indices:
yy3[ind2] = yy[ind1]
yy3[ind1] = yy[ind2]
I don't permute anything, because ind2 a negative value, that maps on to the same element as ind1. yy[-1] is the last item of yy.
[(0, -10), (1, -9), (2, -8),... (9, -1)]
I could work out the details, but I think you should do that yourself - with a small test case. And skip that initial copyto, that just hides errors in the iteration. Print the details, not just summary statistics from large random arrays.
And in the long run you don't want to use an iteration like this. You want to do the permutation with one indexing call. But first get this version working correctly.

Zipping two dataframes in c# Deedle

would anyone be able to provide me with a working example of dataframe zipping in C#? I am bit lost in the operation.
Thanks!
The frame.Zip operation is the same thing as zipAlign in the more documented F# API, so have a look at zipAlign in this section of the documentation.
Given a frame df1:
A
1 -> 1
2 -> 2
And a frame df2:
A
2 -> 2
3 -> 3
When you call df1.Zip(df2, (int a, int b) -> a + b), you get:
A
1 -> <missing>
2 -> 4
3 -> <missing>
That is, for cells where both frames contain a value, a + b is calculated. For all other cells, you get a missing value. Note that you need type annotations in the lambda function - this has to match the type of values in the frame (for not matching types, the function just returns the values from the first frame unchanged).

Understanding PsychoPy's data logging

I have a test PsychoPy Builder script that I am using to investigate some counter-intuitive behaviour. The structure is four routines:
"Init", not in a loop, the following code in "Begin Experiment":
x = 0
y = 0
z = 0
foo = [0, 0, 0]
"One", in a loop, the following code in "End Routine":
x = x + 1
foo[0] = foo[0] + 1
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
"Two", in a loop, the following code in "End Routine":
y = y + 2
foo[1] = foo[1] + 2
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("fooY", foo[1])
thisExp.addData("foo", foo)
"Three", in a loop, the following code in "End Routine":
z = z + 3
foo[2] = foo[2] + 3
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
There is no other code, no other components. The routines "One", "Two", and "Three" form a loop in that order executed five times. The relevant columns of the CSV output file are as follows:
trials.thisRepN trials.thisTrialN trials.thisN trials.thisIndex x y z foo fooY
0 0 0 0 1 2 3 [5, 10, 15] 2
1 0 1 0 2 4 6 [5, 10, 15] 4
2 0 2 0 3 6 9 [5, 10, 15] 6
3 0 3 0 4 8 12 [5, 10, 15] 8
4 0 4 0 5 10 15 [5, 10, 15] 10
Is this the expected output? If so, why? Note that the individual variables, x, y, and z, are displaying updated values each time through the loop (at the end of the loop), while the list foo shows only the final value after the loop iterates all five times, but it shows this in every line. But calling out individual elements of the list displays as individual variables do.
What is the logic and rationale behind this?
Is there a way to make the list output perform as the others do?
Is there a way to force the output to capture/display any of these variables as they are when the addData() is invoked rather than waiting until the end of the loop?
I think I know what is going wrong here. It's probably because python assigns by reference rather than copy. This is explained in detail elsewhere but briefly,
original = [1, 2]
new = original # new is simply a reference to original! It is not a copy.
new[0] = 'Oops' # original is now ['Oops', 2] as is new (which is just a reference or pointer
In your case, the TrialHandler receives the reference, which simply points to the "foo" variable which is updated throughout the experiment. Since the log is only saved in the end of the experiment, all the rows in "foo" now points to the "foo variable" which now holds the value [5, 10, 15].
This assignment-by-reference can be extremely beautiful and handy, but sometimes cause headache like in your example. It applies to all python mutables: lists, dicts, functions, and classes. But not for immutables, like numbers, tuples and strings! That's why your script works for digits but not for the list.
There are different solutions. The simplest is probably to replace the addData calls with thisExp.addData("foo", tuple(foo)) which converts the mutable list to an immutable tuple. One can also do thisExp.addData("foo", [x for x in foo]). A more all-round solution for all kinds of objects is to run import copy in the beginning of the experiment and then add data like thisExp.addData("foo", copy.copy(foo)) in the other codeblocks (if you have a complicated object, use copy.deepcopy instead).

How to format two separate lists in columns, rather than rows in Mathematica?

This seems like it should be a piece of cake, but I haven't found the answer in Mathematica's documentation. Say I have two separate lists, for example x={1,2,3,4,5} and y={1,4,9,16,25}. I want to format these lists as a table with each list as a column, like this:
x y
1 1
2 4
3 9
4 16
5 25
But if I do TableForm[x,y], I get only the first column, like this:
1
2
3
4
5
If I do Grid[{x,y}], I get a table, but formatted as rows instead of columns, like this:
1 2 3 4 5
1 4 9 16 25
Now, if I have my values as {x,y} pairs, rather than separate lists, then I can get almost what I want,like so:
Input: Table[{n,n^2},{n,1,5}]//TableForm
Output:
1 1
2 4
3 9
4 16
5 25
I say almost, because I'd like to have the variable names at the top of each column, and I'd like the columns justified so that the ones digits are always placed vertically in the "ones place", the tens digits in the "tens place", etc.
So, back to my question: If I have two separate lists of the same length, how can I format them as a table of columns? I checked the MMA documentation for Grid and TableForm, but I couldn't find a way to do it. Did I miss something? If there's no direct way to do it, is there a way to transform two separate lists into pairs of values that could then be formatted in columns using TableForm?
Thanks for any suggestions you might have.
Personally I prefer Grid to TableForm. Maybe something like this?
Some preliminaries:
x = {1, 2, 3, 4, 5};
y = {1, 4, 9, 16, 25};
grid = Transpose#{x, y};
headings = {{Item["x", Frame -> {True, True}],
Item["y", Frame -> {True, False}]}};
The following code,
Grid[Join[headings, grid], Alignment -> Right, Dividers -> All,
Spacings -> {3, 1}, FrameStyle -> Orange]
gives this as output, for example:
Often in Mathematica, you use Transpose to switch the role of row and column.
In[6]:= x = {1,2,3,4,5}; y = {1,4,9,16,25};
In[7]:= {x,y} // Transpose // TableForm
Out[7]//TableForm= 1 1
2 4
3 9
4 16
5 25
Instead of using Transpose you can use the option TableDirection:
x={1,2,3,4,5};y={1,4,9,16,25};
TableForm[{x,y},TableDirections->Row,TableHeadings->{{"x","y"}}]
Grid[Transpose[{x, y}], Alignment -> Right]
I would use:
x = {1, 2, 3, 4, 5};
y = {1, 4, 9, 16, 25};
TableForm[{{x, y}}, TableAlignments -> Right]
Here are some more convoluted examples, demonstrating the way TableForm works. It does get complicated, and I usually have to experiment a bit to get what I want.
a = {1, 2, 3};
b = {4, 5, 6};
{a, b} // TableForm
{{a}, {b}} // TableForm
{{{a}}, {{b}}} // TableForm
{{{a}, {b}}} // TableForm
{{List /# a, List /# b}} // TableForm
{{a}, b} // TableForm
{{{a}, b}} // TableForm
{{{a}}, {b}} // TableForm
{{{{a}}, {b}}} // TableForm