1

The question sounds very basic. But when I try to use where or boolean conditions on numpy arrays, it always returns a flattened array.

I have the NumPy array

P = array([[ 0.49530662,  0.07901   , -0.19012371],
       [ 0.1421513 ,  0.48607405, -0.20315014],
       [ 0.76467375,  0.16479826, -0.56598029],
       [ 0.53530718, -0.21166188, -0.08773241]])

I want to extract the array of only negative values, but when I try

P[P<0]
array([-0.19012371, -0.41421612, -0.20315014, -0.56598029, -0.21166188,
       -0.08773241, -0.09241335])
P[np.where(P<0)]
array([-0.19012371, -0.41421612, -0.20315014, -0.56598029, -0.21166188,
       -0.08773241, -0.09241335])

I get a flattened array. How can I extract the array of the form

array([[ 0,  0,          -0.19012371],
       [ 0 , 0,          -0.20315014],
       [ 0,  0,          -0.56598029],
       [ 0, -0.21166188, -0.08773241]])

I do not wish to create a temp array and then use something like Temp[Temp>=0] = 0

5
  • You cannot do that. Reason for that is very simple: NumPy will try to return you what you are asking for, which is all negative values. However, if you want to keep the dimensions, then it would be an array which has an inconsistent dimension length. Therefore, the only way to get to the answer you want, is using the code you are already suggesting. Commented May 2, 2019 at 7:39
  • Just get indexes of all elements above 0 and set them 0! Check my answer below @Shew Commented May 2, 2019 at 7:47
  • The OP wants to extract the array, not convert the existing one. Commented May 2, 2019 at 8:03
  • Yes, another poster already pointed that out, and I have changed my answer accordingly, please take a look @1313e and consider upvoting if possible :) Commented May 2, 2019 at 8:08
  • Next time I suggest you to compose Question with correct output and in general well thought. Also I suggest you to write EDIT when you edit question. Your previous question didnt make sense, but after your edit, it starts to make sense. However my answer now doesnt make sense since you edited your question Commented May 2, 2019 at 8:15

2 Answers 2

3

Since your need is:

I want to "extract" the array of only negative values

You can use numpy.where() with your condition (checking for negative values), which can preserve the dimension of the array, as in the below example:

In [61]: np.where(P<0, P, 0)
Out[61]: 
array([[ 0.        ,  0.        , -0.19012371],
       [ 0.        ,  0.        , -0.20315014],
       [ 0.        ,  0.        , -0.56598029],
       [ 0.        , -0.21166188, -0.08773241]])

where P is your input array.


Another idea could be to use numpy.zeros_like() for initializing a same shape array and numpy.where() to gather the indices at which our condition satisfies.

# initialize our result array with zeros
In [106]: non_positives = np.zeros_like(P)

# gather the indices where our condition is obeyed
In [107]: idxs = np.where(P < 0)

# copy the negative values to correct indices
In [108]: non_positives[idxs] = P[idxs]

In [109]: non_positives
Out[109]: 
array([[ 0.        ,  0.        , -0.19012371],
       [ 0.        ,  0.        , -0.20315014],
       [ 0.        ,  0.        , -0.56598029],
       [ 0.        , -0.21166188, -0.08773241]])

Yet another idea would be to simply use the barebones numpy.clip() API, which would return a new array, if we omit the out= kwarg.

In [22]: np.clip(P, -np.inf, 0)    # P.clip(-np.inf, 0)
Out[22]: 
array([[ 0.        ,  0.        , -0.19012371],
       [ 0.        ,  0.        , -0.20315014],
       [ 0.        ,  0.        , -0.56598029],
       [ 0.        , -0.21166188, -0.08773241]])
Sign up to request clarification or add additional context in comments.

Comments

0

This should work, essentially get the indexes of all elements which are above 0, and set them to 0, this will preserve the dimensions! I got the idea from here: Replace all elements of Python NumPy Array that are greater than some value

Also note that I have modified the original array, I haven't used a temp array here

import numpy as np

P = np.array([[ 0.49530662,  0.07901   , -0.19012371],
       [ 0.1421513 ,  0.48607405, -0.20315014],
       [ 0.76467375,  0.16479826, -0.56598029],
       [ 0.53530718, -0.21166188, -0.08773241]])

P[P >= 0] = 0
print(P)

The output will be

[[ 0.          0.         -0.19012371]
 [ 0.          0.         -0.20315014]
 [ 0.          0.         -0.56598029]
 [ 0.         -0.21166188 -0.08773241]]

As noted below, this will modify the array, so we should use np.where(P<0, P 0) to preserve the original array as follows, thanks @kmario123 as follows

import numpy as np

P = np.array([[ 0.49530662,  0.07901   , -0.19012371],
       [ 0.1421513 ,  0.48607405, -0.20315014],
       [ 0.76467375,  0.16479826, -0.56598029],
       [ 0.53530718, -0.21166188, -0.08773241]])

print( np.where(P<0, P, 0))
print(P)

The output will be

[[ 0.          0.         -0.19012371]
 [ 0.          0.         -0.20315014]
 [ 0.          0.         -0.56598029]
 [ 0.         -0.21166188 -0.08773241]]
[[ 0.49530662  0.07901    -0.19012371]
 [ 0.1421513   0.48607405 -0.20315014]
 [ 0.76467375  0.16479826 -0.56598029]
 [ 0.53530718 -0.21166188 -0.08773241]]

2 Comments

Please note that this will modify the original array, forever.
Thanks for the observation, I have updated the answer and mentioned the caveat in the old answer, and also mentioned you in the updated way, please check if it looks good @kmario23 and upvote if possible :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.