Reputation: 306
I have the following 2d numpy array:
array_a = np.array([[6.2, 2.0, 5.5, 8.0], [6.0, 5.1, 7.1, 8.2], ...])
I also have a list of lists of indices (sizes of lists vary) represent values that I want to pick from that array.
wanted_values = [[0,3], [1,2,3], ...]
In the end, I want to have a 2d numpy array where each row only has values that correspond to these indices. The desired output would look like this:
np.array([[6.2, 8.0], [5.1, 7.1, 8.2], ...])
I converted list of indices to a numpy array and a warning saying that "Creating an ndarray from ragged nested sequences is deprecated". Then, I applied take function to the numpy array and got an error:
a.take(wanted_values)
TypeError: Cannot cast array data from dtype('O') to dtype('int64') according to the rule 'safe'
How can I achieve the desired result? Is there a better way to go about this?
Upvotes: 0
Views: 355
Reputation: 131
You are having a problem with the size of the rows in your array. Consider the following example
>>> a = np.array([[1],[1,2]])
<stdin>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested
sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different
lengths or shapes) is deprecated. If you meant to do this, you must specify
'dtype=object' when creating the ndarray
Moreover, numpy function take
does not work as you expect. That is, given numpy admitted ragged nested sequences what the function does is:
wanted_values
and places them in the same manner they are placed in wanted_values
that is your code would give np.array([6.2, 8.0],[2.0, 5.5, 8.0], ...])
that is different from what you are expecting.What I suggest you to do is store every selection in a list choices that you build iterating both iterables at the same time:
array_a = np.array([[6.2, 2.0, 5.5, 8.0], [6.0, 5.1, 7.1, 8.2]])
wanted_values = [[0,3], [1,2,3]]
choice = []
for xs, indices in zip(array_a, wanted_values):
choice.append(xs[indices])
Upvotes: 0
Reputation: 2111
Work it from here
[array_a[i][wanted_values[i]] for i in range(len(wanted_values))]
#output
[array([6.2, 8. ]), array([5.1, 7.1, 8.2])]
Upvotes: 1