Jules
Jules

Reputation: 7

Change values in array (condition) with values from another list

I have the following list:

indices
>>> [21, 43, 58, 64, 88, 104, 113, 115, 120]

I want every occurrence of these values in this list -1 (so 20, 42, 57, etc.) to be zeroed out from a 3D array 'q' I have.

I have tried list comprehensions, for and if loops (see below), but I always get the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I haven't been able to resolve this.

Any help would be amazing!

>>> for b in q:
...     for u in indices:
...         if b==u:
...             b==0


>>> for u in indices:
...     q = [0 if x==u else x for x in q]

Upvotes: 0

Views: 132

Answers (3)

J. Torrecilla
J. Torrecilla

Reputation: 36

I think this is a short and efficient way:

b= b*np.logical_not(np.reshape(np.in1d(b,indices),b.shape))

with np.in1d() we have a boolean array with True where the element in b is in indices. We reshape it to be the as b and then negate, so that we have False (or, if you want, 0) where we want to zero b. Just multiply this matrix element wise with b and you got it

It has the advantage that it works for 1D, 2D, 3D, ... arrays

Upvotes: 0

Nate Schultz
Nate Schultz

Reputation: 191

I tried this and it worked for me:

>>> arr_2D = [3,4,5,6]
>>> arr_3D = [[3,4,5,6],[2,3,4,5],[4,5,6,7,8,8]]
>>> for el in arr_2D:
...    for x in arr_3D:
...       for y in x:
...          if y == el - 1:
...             x.remove(y)
... 
>>> arr_3D
[[6], [], [6, 7, 8, 8]]

Doing it with list comprehensions seams like it might be overkill in this situation.

Or to zero out instead of remove

>>> for el in arr_2D:
...    for x in range(len(arr_3D)):
...       for y in range(len(arr_3D[x])):
...           if arr_3D[x][y] == el - 1:
...               arr_3D[x][y] = 0
... 
>>> arr_3D
[[0, 0, 0, 6], [0, 0, 0, 0], [0, 0, 6, 7, 8, 8]]

Here is the list comprehension:

zero_out = lambda arr_2D, arr_3D: [[0 if x in [el-1 for el in arr_2D] else x for x in y] for y in arr_3D]

Upvotes: 0

gold_cy
gold_cy

Reputation: 14216

How about this?

indices = range(1, 10)
>>[1, 2, 3, 4, 5, 6, 7, 8, 9]

q = np.arange(12).reshape(2,2,3)
array([[[ 0,  1,  2],
        [ 3,  4,  5]],

       [[ 6,  7,  8],
        [ 9, 10, 11]]])

def zeroed(row):
    new_indices = map(lambda x: x-1, indices)
    nrow = [0 if elem in new_indices else elem for elem in row]
    return now

np.apply_along_axis(zeroed, 1, q)

array([[[ 0,  0,  0],
        [ 0,  0,  0]],

       [[ 0,  0,  0],
        [ 9, 10, 11]]])

Upvotes: 0

Related Questions