Булево индексирование Python 3.7 * предупреждение * с использованием 'list' - PullRequest
0 голосов
/ 15 марта 2019
  • Возьмите очень большой список, чтобы по ряду причин он и все остальные не помещались в доступную память, здесь: A = [ 2, -3, 10, 0.2]
  • Отобразите знак его компонентов:sign_A = list(map(lambda u: (abs(u)==u), A))
    Вы получаете [True, False, True, True]
  • Выполните некоторую логику, где вам нужно работать на abs_A = [abs(e) for e in A].Итак, вы сбрасываете A и продолжаете работать с sign_A и abs_A.Логика выдает интересующие индексы компонентов, скажем i, k, ... для списка abs_A.

Проблема, с которой я сталкиваюсь при использовании троичного оператора (falsevalue, truevalue)[condition]сделать некоторую алгебру для со знаком компонентов A, например:

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

Я получаю это предупреждение:

DeprecationWarning: В будущем скаляры 'np.bool_' будут ошибочно интерпретироваться как индекс.

Предупреждение косвенно говорит мне, что, вероятно, лучше, более "питонский" способ, чем мой фрагмент, чтобы сделать это.Я нашел соответствующие посты (например, здесь и здесь ), но нет предложений относительно того, как мне с этим бороться.Указывает кто-нибудь?

Ответы [ 3 ]

2 голосов
/ 15 марта 2019

Со списками логическое индексирование работает нормально:

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

Мы получаем предупреждение, если пытаемся индексировать с помощью булевого индекса:

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

Мы можем обойти этосделав массив sign_A целым числом справа от начала:

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

Если мы начнем с массива:

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

массив знаков - используя where для непосредственного отображения на(-1,1) пробел

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

массив abs:

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

воссозданный массив:

In [33]: abs_B*sign_B                                                           
Out[33]: array([ 2. , -3. , 10. ,  0.2])
0 голосов
/ 09 июня 2019

Простым решением здесь является использование синтаксиса truevalue if condition else falsevalue вместо (falsevalue, truevalue)[condition].

0 голосов
/ 15 марта 2019

Чтобы избежать предупреждения, замените np.bool() на int():

abs_A[i]*(-1, 1)[int(sign_A[i])] + ...
...