Логический оператор для булевой индексации в панд

Я работаю с булевым индексом в панд. Вопрос в том, почему утверждение:

a[(a['some_column']==some_number) & (a['some_other_column']==some_other_number)]

работает, а

a[(a['some_column']==some_number) and (a['some_other_column']==some_other_number)]
ошибки?

пример:

a=pd.DataFrame({'x':[1,1],'y':[10,20]})

In: a[(a['x']==1)&(a['y']==10)]
Out:    x   y
     0  1  10

In: a[(a['x']==1) and (a['y']==10)]
Out: ValueError: The truth value of an array with more than one element is ambiguous.     Use a.any() or a.all()

1 ответов


когда вы говорите

(a['x']==1) and (a['y']==10)

вы неявно просите Python преобразовать (a['x']==1) и (a['y']==10) к логическим значениям.

массивы NumPy (длиной более 1) и объекты Pandas, такие как Series, не имеют логического значения-другими словами, они поднимают

ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().

при использовании в качестве логического значения. Это потому, что его неясно, когда это должно быть True или False. Некоторые пользователи могут предположить, что они истинны, если они имеют ненулевую длину, как список Python. Другие могут желать, чтобы это было правдой, только если все ее элементы истинны. Другие могут хотеть, чтобы это было правдой, если любой из его элементов верны.

поскольку существует так много противоречивых ожиданий, дизайнеры NumPy и Pandas отказываются угадывать, а вместо этого поднимают ValueError.

вместо этого вы должны быть явными, вызывая empty(), all() или any() метод, чтобы указать, какое поведение жаждать.

в этом случае, однако, похоже, что вы не хотите логической оценки, вы хотите элемент-мудрый логично-а. Вот что такое & бинарный оператор выполняет:

(a['x']==1) & (a['y']==10)

возвращает булевский массив.


кстати, как alexpmil Примечания, скобки обязательны, так как & выше приоритет операторов чем ==. Без скобок, a['x']==1 & a['y']==10 будет оценивается как a['x'] == (1 & a['y']) == 10 что, в свою очередь, будет эквивалентно цепному сравнению (a['x'] == (1 & a['y'])) and ((1 & a['y']) == 10). Это выражение формы Series and Series. Использование and С двумя сериями снова вызовет то же самое ValueError как выше. Вот почему скобки обязательны.