Select One Element in Each Row of a Numpy Array by Column Indices [duplicate] - select

This question already has answers here:
NumPy selecting specific column index per row by using a list of indexes
(7 answers)
Closed 2 years ago.
Is there a better way to get the "output_array" from the "input_array" and "select_id" ?
Can we get rid of range( input_array.shape[0] ) ?
>>> input_array = numpy.array( [ [3,14], [12, 5], [75, 50] ] )
>>> select_id = [0, 1, 1]
>>> print input_array
[[ 3 14]
[12 5]
[75 50]]
>>> output_array = input_array[ range( input_array.shape[0] ), select_id ]
>>> print output_array
[ 3 5 50]

You can choose from given array using numpy.choose which constructs an array from an index array (in your case select_id) and a set of arrays (in your case input_array) to choose from. However you may first need to transpose input_array to match dimensions. The following shows a small example:
In [101]: input_array
Out[101]:
array([[ 3, 14],
[12, 5],
[75, 50]])
In [102]: input_array.shape
Out[102]: (3, 2)
In [103]: select_id
Out[103]: [0, 1, 1]
In [104]: output_array = np.choose(select_id, input_array.T)
In [105]: output_array
Out[105]: array([ 3, 5, 50])

(because I can't post this as a comment on the accepted answer)
Note that numpy.choose only works if you have 32 or fewer choices (in this case, the dimension of your array along which you're indexing must be of size 32 or smaller). Additionally, the documentation for numpy.choose says
To reduce the chance of misinterpretation, even though the following "abuse" is nominally supported, choices should neither be, nor be thought of as, a single array, i.e., the outermost sequence-like container should be either a list or a tuple.
The OP asks:
Is there a better way to get the output_array from the input_array and select_id?
I would say, the way you originally suggested seems the best out of those presented here. It is easy to understand, scales to large arrays, and is efficient.
Can we get rid of range(input_array.shape[0])?
Yes, as shown by other answers, but the accepted one doesn't work in general so well as what the OP already suggests doing.

I think enumerate is handy.
[input_array[enum, item] for enum, item in enumerate(select_id)]

How about:
[input_array[x,y] for x,y in zip(range(len(input_array[:,0])),select_id)]

Related

How to do multiple where query without effect data in TypeORM?

I want to do multiple where query without effect data. I want to get data that include at least 1 data per array. Pseudo code
data =[1,3]
array1 = [1,2]
array2 = [3,4]
if(data.IsIntersect(array1) and data.IsIntersect(array2))
IsIntersect checks are there a intersection beetween arrays
I did so far
queryBuilder.andWhere(
'properties.id IN (:...sizeIds) AND properties.id IN (:...colorIds)',
{ sizeIds: [1, 2], colorIds: [3, 4] },
);
It returns empty because firstly checks properties for 'sizeIds' then it checks for 'colorIds'. For example
properties includes 1,3
check for sizeIds, returns 1
check for colorIds, return empty
How can I do that with typeORM?
How can properties.id be 1 and 3? And if it is, how could 1 or 3 be in both? You're asking for the impossible.
I assume you mean to ask for when properties.id is 1 or 3, because if it is [1,3] then you should use the postgres array syntax {1,3} & the ANY keyword (some variation on this: Check if value exists in Postgres array).
tldr, I think all you need is brackets and OR instead of AND:
queryBuilder.andWhere(
'(properties.id IN (:...sizeIds) OR properties.id IN (:...colorIds))',
{ sizeIds: [1, 2], colorIds: [3, 4] },
);
If properties.id is in fact an array, then please add the entity definition to your question. If you want to merge the rows where properties.id is in the list you will need a GROUP BY (https://orkhan.gitbook.io/typeorm/docs/select-query-builder).

From which direction swift starts to read dictionaries? [duplicate]

This question already has an answer here:
For loop for Dictionary don't follow it's order in Swift [duplicate]
(1 answer)
Closed 5 years ago.
the question that I want to ask, from which directions swift starts to read dictionaries or arrays
when I put some codes like this
let interestingNumber = [
"Square": [1,4,9,16,25],
"Prime": [2,3,5,7,11,13],
"Fiboannci": [1,1,2,3,5,8],
"asd":[2,3,4,5],
"zxc":[3,4,5]
]
for (key,values) in interestingNumber{
print(values)
}
the output is
[1, 4, 9, 16, 25]
[2, 3, 5, 7, 11, 13]
[1, 1, 2, 3, 5, 8]
[3, 4, 5]
[2, 3, 4, 5]
this is not the exact order, so do you know why swift does this ? and it sometimes makes it different too!
I guessed may be it does it in string order, then I tried but I think it is not too, so why swift does do that ?
Just like for NSDictionary, Swift dictionaries are not ordered by key or value. The order will always be unspecified.
If you need the keys to be sorted, your only option is to have an array of ordered keys, and use the for loop over this array.
From apple documentation (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html#//apple_ref/doc/uid/TP40014097-CH8-ID105)
Dictionaries
A dictionary stores associations between keys of the same type and
values of the same type in a collection with no defined ordering. Each
value is associated with a unique key, which acts as an identifier for
that value within the dictionary. Unlike items in an array, items in a
dictionary do not have a specified order. You use a dictionary when
you need to look up values based on their identifier, in much the same
way that a real-world dictionary is used to look up the definition for
a particular word.

Sort all dimensions of a cell array from min to max in MATLAB

I have created a cell array called Items of size (10,5). It contains the following as the first column in the cell array:
Item name Price (in $) Shipping (in $) Total price (in $) Total price (in €)
I have it all filled up, but what I need to do is to sort the cell array according to the total price in € from the smallest to the largest, but I can't seem to find a way to do it. I tried sort(Items,5); in order to sort according to the values in € but it returns an error. It could be useful to find a way to make the sorting automatic, so if I wanted to add more items it would still sort them in the global list.
sortrows will likely do exactly what you want to do. It will sort based on a specific column, assuming the datatype is constant in the entire column.
>> a ={'a',8,9;'b',5,6;'c',2,3};
>> a_sorted = sortrows(a,3)
a_sortred =
'c' [2] [3]
'b' [5] [6]
'a' [8] [9]
Edit
From your comments below, you can easily just sort the array first and then add a row to the cell array the same way you would combine regular arrays. Documentation
>> a = {7,8,9;4,5,6;1,2,3};
>> a_sorted = sortrows(a,3);
>> headers = {'col1','col2','col3'};
>> a_header = [headers;a_sorted]
a_header =
'col1' 'col2' 'col3'
[ 1] [ 2] [ 3]
[ 4] [ 5] [ 6]
[ 7] [ 8] [ 9]
EDIT #2
You can round the values that you are presenting using the second argument of the round function. After you round it, you can change the format of how things are displayed. Normally it is set as short, which is 4 decimal places. If you set it to shortg it will show as few decimals as possible, up to 4.
>> a = [1.23456789;2.3456789;3.456789]
a =
1.2346
2.3457
3.4568
>> a_rounded = round(a,2)
a_rounded =
1.2300
2.3500
3.4600
>> format shortg
>> a_rounded
a_rounded =
1.23
2.35
3.46
If changing the format is not an option, you could always just convert the number into a string and then display that. That gets a little more complicated, but a quick google will help you there.
EDIT #3
I did not know this existed before, but you can apparently use the format style called bank. This will display all numbers as two decimal points even if they are 0.
First place all of the prices in a separate array, sort on this array individually then use the indices of sorting to rearrange the rows of your cell array.
Try something like this:
price = [Items{:,5}];
[~,ind] = sort(price);
ItemsSorted = Items(ind,:);
Alternatively you can use the sortrows function that MZimmerman6 mentioned and operate along the fifth column of your cell array. I wasn't aware it worked on cell arrays, so I learned something new!

How can I select certain rows in a dataset? Mathematica

My question is probably really easy, but I am a mathematica beginner.
I have a dataset, lets say:
Column: Numbers from 1 to 10
Column Signs
Column Other signs.
{{1,2,3,4,5,6,7,8,9,10},{d,t,4,/,g,t,w,o,p,m},{g,h,j,k,l,s,d,e,w,q}}
Now I want to extract all rows for which column 1 provides an odd number. In other words I want to create a new dataset.
I tried to work with Select and OddQ as well as with the IF function, but I have absolutely no clue how to put this orders in the right way!
Taking a stab at what you might be asking..
(table = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ,
Characters["abcdefghij"],
Characters["ABCDEFGHIJ"]}) // MatrixForm
table[[All, 1 ;; -1 ;; 2]] // MatrixForm
or perhaps this:
Select[table, OddQ[#[[1]]] &]
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
The convention in Mathematica is the reverse of what you use in your description.
Rows are first level sublists.
Let's take your original data
mytable = {{1,2,3,4,5,6,7,8,9,10},{d,t,4,"/",g,t,w,o,p,m},{g,h,j,k,l,s,d,e,w,q}}
Just as you suggested, Select and OddQ can do what you want, but on your table, transposed. So we transpose first and back:
Transpose[Select[Transpose[mytable], OddQ[First[#]]& ]]
Another way:
Mathematica functional command MapThread can work on synchronous lists.
DeleteCases[MapThread[If[OddQ[#1], {##}] &, mytable], Null]
The inner function of MapThread gets all elements of what you call a 'row' as variables (#1, #2, etc.). So it test the first column and outputs all columns or a Null if the test fails. The enclosing DeleteCases suppresses the unmatching "rows".

MATLAB, how to evaluate multiple indices in one line?

I don't know how to explain this better than by giving you an example.
Suppose I have the following array:
a = magic(6)
And then I take a 'slice' of that like this:
a(:,1)
It will print:
35
3
31
8
30
4
Now I want the first number, so I want to write:
a(:,1)(1)
Instead of:
b = a(:,1)
b(1)
Also, is there a way to do something like this (assignment and comparison, i.e. set b, then evaluate against it):
(b = a(:,1))(1)
Ok, here's an update with a function where it isn't trivial to use a(1, 1)
come_on = sprintf('%i, ', magic(3));
come_on(1:end-2)
8, 3, 4, 1, 5, 9, 6, 7, 2
Also, what if I only want the first 4 numbers on magic(3)?
It would be better to write
sprintf('%i, ', magic(3)(1:4))(1:end-2)
instead of tens of lines, MHO.
You cannot concatenate indexing as foo(1)(2)(3). However, you can index multiple dimensions at once. So in this case, a(1,1) will give you what you want.