Matthew Ciaramitaro Matthew Ciaramitaro - 3 years ago 272
Python Question

Converting values of Existing Numpy ndarray to tuples

Let's say I have a

numpy.ndarray
with
shape (2,3,2)
as below,

arr = np.array([[[1,3], [2,5], [1,2]],[[3,3], [6,5], [5,2]]])


I want to reshape it in such a way that:

arr.shape == (2,3)
arr == [[(1,3), (2,5), (1,2)],[(3,3), (6,5), (5,2)]]


and
each value of
arr
is a size 2
tuple


The reason I want to do this is that I want to take the minimum along axis 0 of the 3dimensional array, but I want to preserve the value that the min of the rows in paired with.

arr = np.array(
[[[1, 4],
[2, 1],
[5, 2]],

[[3, 3],
[6, 5],
[1, 7]]])

print(np.min(arr, axis=0))
>>> [[1,3],
[2,1],
[1,2]]
>>>Should be
[[1,4],
[2,1],
[1,7]]


If the array contained tuples, it would be 2 dimensional, and the comparison operator for minimize would still function correctly,
so I would get the correct result. But I haven't found any way to do this besides iterating over the arrays, which is inefficient and obvious in implementation.

Is it possible to perform this conversion efficiently in numpy?

Answer Source

First, let's find out which pairs to take:

first_eq = arr[0,:,0] == arr[1,:,0]
which_compare = np.where(first_eq, 1, 0)[0]
winner = arr[:,:,which_compare].argmin(axis=0)

Here, first_eq is True where the first elements match, so we would need to compare the second elements. It's [False, False, False] in your example. which_compare then is [0, 0, 0] (because the first element of each pair is what we will compare). Finally, winner tells us which of the two pairs to choose along the second axis. It is [0, 0, 1].

The last step is to extract the winners:

arr[winner, np.arange(arr.shape[1])]

That is, take the winner (0 or 1) at each point along the second axis.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download