Home > Enterprise >  Replace arrays in ndarray based on condition
Replace arrays in ndarray based on condition

Time:06-24

This question is about replacing entire arrays if they fulfil conditions. It is not about replacing individual values in an ndarray - as in this and this question for example.


Problem

I have an input array inarray. As an example:

import numpy as np
inarray = \
np.array([[[1,1,1,1],
           [2,2,2,2]],
          [[3,3,3,3],
           [4,4,4,4]]])

I would like to replace the rows containing [1,1,1,1] by [9,9,9,9].

I suspect there is a more efficient way of doing this than my method below. What is it?


My attempt

I do:

inarray[np.equal(inarray,np.array([1,1,1,1])).all(axis=2)]=np.array([9,9,9,9])

This line changes inarray to be:

array([[[9, 9, 9, 9],
        [2, 2, 2, 2]],

       [[3, 3, 3, 3],
        [4, 4, 4, 4]]])

as expected.


Problem with other methods

One suggested way by this answer is to use:

inarray[inarray == [1,1,1,1]] = [9,9,9,9]

The problem with this is that when [1,1,1,1] appears multiple times, this fails:

inarray = \
np.array([[[1,1,1,1],
           [2,2,2,2]],
          [[1,1,1,1],
           [4,4,4,4]]])

inarray[inarray == [1,1,1,1]] = [9,9,9,9]

Output:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [81], in <cell line: 1>()
----> 1 inarray[inarray == [1,1,1,1]] = [9,9,9,9]

ValueError: NumPy boolean array indexing assignment cannot assign 4 input values to the 8 output values where the mask is true

Expected result is inarray having been changed to:

array([[[9, 9, 9, 9],
        [2, 2, 2, 2]],

       [[9, 9, 9, 9],
        [4, 4, 4, 4]]])

CodePudding user response:

If I understand your question correctly, this should work

inarray[inarray == [1,1,1,1]] = [9,9,9,9]

It basically matches where inarray equals [1,1,1,1]and makes it [9,9,9,9]

Edit

Well you can then modify slightly your code to this

inarray[(inarray==np.array([1,1,1,1])).all(axis=2)]=[9,9,9,9]

But it really does not make a big difference

  • Related