mark mark
mark mark

Reputation: 306

Applying numpy take function to 2d array

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

Answers (2)

Diego Asterio
Diego Asterio

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:

  1. It flattens the array ,
  2. it takes elements from that flattened array indexed by the numbers inside the second argument of the function in your case 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

ombk
ombk

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

Related Questions