5

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.

4 Answers 4

9

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]]
Sign up to request clarification or add additional context in comments.

2 Comments

I only seem to be able to do this to one column at a time... and the rest is ignored. arr1 = np.array([[1, 0, np.nan], [2, np.nan, np.nan], [3, 9, np.nan]]) arr1[:,1][arr1[:,1] == 0] = -1 arr1[:,2][arr1[:,2] == np.nan] = -2 The 1st replacement of 0 with -1, is done, but NaN in the 3rd column is not replaced by -2. Why is this? (I am very new to Python, and finding it extremely confusing)
@GenDemo One can't use the equality operator to check for NaNs. Instead use the np.isnan function. So either arr1[:,2][np.isnan(arr1[:,2])] = -2 or, as in my answer below regarding the multiple-columns case: arr1[:,2] = np.where(np.isnan(arr1[:,2]),-2,arr1[:,2])
2

Try the following:

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

You could also use np.where.

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

1 Comment

These are great answers too, but I can't mark both as answers, so I awarded the answer to the first to respond. Thanks for your help!
0

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.

Comments

0

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]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.