2

Need to compare each value inside a numpy array and return 1 to the largest value and 0 to the others. I am having problem with different numbers of [].

Input Example:

[[[0.6673975 0.33333233]]
.
.
.
[[0.33260247 0.6673975]]]

Expected Output:

[[[1 0]]
.
.
.
[[0 1]]]
Eduardo Andrade
  • 111
  • 1
  • 1
  • 13
  • what is your criteria for the comparison? numpy is really good at these things, plenty of examples around. check out `np.where` for starters, assuming that you want to know which one is the biggest I would start with `np.diff` – ahed87 Nov 29 '17 at 21:00

2 Answers2

1

Let's create an example case to work with:

a = np.array([[1, 2, 3], [4, 6, 5], [9, 1, 1]])

then we can iterate through with a for-loop over the last row (second last axis) and modify that axis accordingly:

for i in range(a.shape[-2]):
    a[..., i, :] = a[..., i, :] == max(a[..., i, :])

And this will modify a to the correct result:

array([[0, 0, 1],
       [0, 1, 0],
       [1, 0, 0]])

And this same method will work for any rectangular array, such as:

a = np.array([[1, 2], [4, 3], [9, 7]])

giving:

array([[0, 1],
       [1, 0],
       [1, 0]])
Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
  • Thank you! When I do print(np.shape(my_array)) it shows me (1, 1, 2) and print(my_array) is returning [[[1. 1.]]] for everything. – Eduardo Andrade Nov 29 '17 at 21:38
  • Please post the full contents of your `my_array` in the question so people can see what is going on... – Joe Iddon Nov 29 '17 at 21:47
1

Max over axis:

If, as suggested by Joe in the comments, you're looking for a maximum along an axis, then, for axis axis,

np.moveaxis((np.moveaxis(ar, axis, 0) == ar.max(axis)).astype(int), 0, axis)

or, a bit faster,

(ar == np.broadcast_to(np.expand_dims(ar.max(axis), axis), ar.shape)).astype(int)

Should cover the n-dimensional case.

Ex:

ar = np.random.randint(0, 100, (2, 3, 4))

ar
Out[157]: 
array([[[17, 28, 22, 31],
        [99, 51, 65, 65],
        [46, 24, 93,  4]],

       [[ 5, 84, 85, 79],
        [ 7, 80, 27, 25],
        [46, 80, 90,  3]]])

(ar == np.broadcast_to(np.expand_dims(ar.max(-1), -1), ar.shape)).astype(int)
Out[159]: 
array([[[0, 0, 0, 1],
        [1, 0, 0, 0],
        [0, 0, 1, 0]],

       [[0, 0, 1, 0],
        [0, 1, 0, 0],
        [0, 0, 1, 0]]])
ar.max(-1)
Out[160]: 
array([[31, 99, 93],
       [85, 80, 90]])

Max over full array:

On the off-chance you're trying to identify elements equal to the maximum over the whole array,

(ar == ar.max()).astype(int)

should give what you're looking for.

EFT
  • 2,359
  • 1
  • 10
  • 11
  • The OP wanted the `max` value in each row, not a `1` for the `max` value in the entire `array` so I'm afraid this doesn't solve the problem. – Joe Iddon Nov 29 '17 at 21:10
  • @JoeIddon The question does not specify. The max for both rows in the example is the same. I'll add a solution addressing your concern, though. – EFT Nov 29 '17 at 21:18