Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.7 boolean indexing *warning* using 'list'

  • Take a very large list such that for any number of reasons it and all the rest to come does not fit in available memory, here: A = [ 2, -3, 10, 0.2]
  • Map the sign of its components: sign_A = list(map(lambda u: (abs(u)==u), A))
    You get [True, False, True, True]
  • Do some logic where you need to operate on abs_A = [abs(e) for e in A]. So you flush A and you keep working with sign_A and abs_A. The logic yields components' indices of interest, say i, k, ... for the list abs_A.

The problem I have is when using the ternary operator (falsevalue, truevalue)[condition] to do some algebra on the signed components of A, e.g.:

abs_A[i]*(-1, 1)[sign_A[i]] + abs_A[k]**(-1, 1)[sign_A[k]]
# equivalently, can use:
# abs_A[i]*(-1, 1)[np.bool(sign_A[i])] + abs_A[k]**(-1, 1)[np.bool(sign_A[k])]

I get this warning:

DeprecationWarning: In future, it will be an error for 'np.bool_' scalars to be interpreted as an index.

The warning indirectly tells me that there is probably a better, more "pythonesque" way than my snippet to do this. I found relevant posts (e.g. here and here) but no suggestion as to how I should deal with it. Pointers anyone ?

like image 460
Cbhihe Avatar asked Jul 26 '26 08:07

Cbhihe


1 Answers

With lists, the boolean indexing works fine:

In [21]: A = [ 2, -3, 10, 0.2]                                                  
In [22]: sign_A = list(map(lambda u: (abs(u)==u), A))                           
In [23]: abs_A = [abs(e) for e in A]                                            
In [24]: i=0; k=1                                                               
In [25]: abs_A[i]*(-1, 1)[sign_A[i]] + abs_A[k]**(-1, 1)[sign_A[k]]             
Out[25]: 2.3333333333333335

We do get the warning if we try to index with a numpy boolean:

In [26]: abs_A[i]*(-1, 1)[np.array(sign_A)[i]]                                  
/usr/local/bin/ipython3:1: DeprecationWarning: In future, it will be an error for 'np.bool_' scalars to be interpreted as an index
  #!/usr/bin/python3
Out[26]: 2

We can get around that by making the sign_A array integer right from the start:

In [27]: abs_A[i]*(-1, 1)[np.array(sign_A,dtype=int)[i]]                        
Out[27]: 2

If we start with an array:

In [28]: B = np.array(A)                                                        

the sign array - using where to map directly onto (-1,1) space

In [30]: sign_B = np.where(B>=0,1,-1)                                           
In [31]: sign_B                                                                 
Out[31]: array([ 1, -1,  1,  1])

the abs array:

In [32]: abs_B = np.abs(B)                                                      

the recreated array:

In [33]: abs_B*sign_B                                                           
Out[33]: array([ 2. , -3. , 10. ,  0.2])
like image 160
hpaulj Avatar answered Jul 28 '26 07:07

hpaulj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!