Conditional Replace within a Column of a Numpy Array

Question:

I have a numpy array, for example:

theData= [[0, 1, 1, 1],[0, 1, 3, 1],[3, 4, 1, 3],[0, 1, 2, 0],[2, 1, 0, 0]]

How do I replace all the zeros in the first column with -1?

It’s easy to replace all the zeros in the whole array with theData[theData==0] = -1, so I thought something like this would work

theData[theData[:,0] == 0] = -1
theData[:,0 == 0] = -1

but these change all values across the row to -1 for any row in which the first column value is zero. Not my goal, I want to limit the replacement to the first (or whatever) column.

This can obviously be done with a loop. It can also be done by extracting the first column as 1D array, doing the replacement within it, then copying its transpose over the original first column. But I suspect there is a faster and more Pythonic way to do this. Perhaps using np.where, but I can’t figure it out.

Asked By: Aaron Bramson

||

Answers:

You can index that column directly as long as you don’t build a different object with it. Check the following example:

theData= np.array([[0, 1, 1, 1],[0, 1, 3, 1],[3, 4, 1, 3],[0, 1, 2, 0],[2, 1, 0, 0]])
print(theData)
theData[:,0][theData[:,0] == 0] = -1
print(theData)

The result is this:

[[0 1 1 1]
 [0 1 3 1]
 [3 4 1 3]
 [0 1 2 0]
 [2 1 0 0]]
[[-1  1  1  1]
 [-1  1  3  1]
 [ 3  4  1  3]
 [-1  1  2  0]
 [ 2  1  0  0]]
Answered By: armatita

Try the following:

theData[theData[:,0]==0, 0] = -1

You could also use np.where.

theData[np.where(theData[:,[0]]==0)] = -1
Answered By: miindlek

If you wanted to subset with more than one column, you’d have to use np.where().

Example:

theData= np.array([[0, 1, 1, 1],[0, 1, 3, 1],[3, 4, 1, 3],[0, 1, 2, 0],[2, 1, 0, 0]])
print(theData)
theData[:, [0, 1]][theData[:, [0, 1]] == 0] = -1 # Notice it's [0, 1] instead of [0]
print(theData)

The output is:

[[0 1 1 1]
 [0 1 3 1]
 [3 4 1 3]
 [0 1 2 0]
 [2 1 0 0]]
[[0 1 1 1]
 [0 1 3 1]
 [3 4 1 3]
 [0 1 2 0]
 [2 1 0 0]]

So the array (theData) didn’t change. But if you do

theData[np.where(theData[:, [0, 1]] == 0)] = -1
print(theData)

you get

[[-1  1  1  1]
 [-1  1  3  1]
 [ 3  4  1  3]
 [-1  1  2  0]
 [ 2  1  0  0]]

It also looks cleaner.

Answered By: David Pinho

For the multiple-columns case, while David Pinho’s method works in their example, it only works because they picked the first two columns (denoted by indices 0 and 1). If you wanted to change values in the first and third columns (indices 0 and 2) but had done

theData[np.where(theData[:, [0, 2]] == 0)] = -1
print(theData)

you get

[[-1  1  1  1]
 [-1  1  3  1]
 [ 3  4  1  3]
 [-1  1  2  0]
 [ 2  -1  0  0]]

A correct way of doing this would be

theData[:,[0,2]] = np.where(theData[:,[0,2]]==0,-1,theData[:,[0,2]])

yielding

[[-1  1  1  1]
 [-1  1  3  1]
 [ 3  4  1  3]
 [-1  1  2  0]
 [ 2  1  -1  0]]
Answered By: Alex
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.