Я фильтрую строки в кадре данных по значениям в двух столбцах.
По какой-то причине оператор ИЛИ ведет себя так, как я ожидал, что оператор И будет вести себя, и наоборот.
Мой тестовый код:
import pandas as pd
df = pd.DataFrame({'a': range(5), 'b': range(5) })
# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1
df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]
print pd.concat([df, df1, df2], axis=1,
keys = [ 'original df', 'using AND (&)', 'using OR (|)',])
И результат:
original df using AND (&) using OR (|)
a b a b a b
0 0 0 0 0 0 0
1 -1 -1 NaN NaN NaN NaN
2 2 2 2 2 2 2
3 -1 3 NaN NaN -1 3
4 4 -1 NaN NaN 4 -1
[5 rows x 6 columns]
Как видите, AND
оператор отбрасывает каждую строку, в которой хотя бы одно значение равно -1
. С другой стороны, OR
оператор требует, чтобы оба значения были равны, -1
чтобы отбросить их. Я ожидал прямо противоположного результата. Кто-нибудь может объяснить такое поведение, пожалуйста?
Я использую pandas 0.13.1.
python
pandas
boolean-logic
Войцех Вальчак
источник
источник
df.query
иpd.eval
кажутся хорошими для этого варианта использования. Для получения информации оpd.eval()
семействе функций, их возможностях и вариантах использования посетите страницу Dynamic Expression Evaluation в pandas, используя pd.eval () .Ответы:
Это правильно. Помните, что вы пишете условие в терминах того, что вы хотите сохранить , а не в терминах того, что вы хотите отказаться. Для
df1
:Вы говорите «сохранить строки, в которых
df.a
не -1 иdf.b
не -1», что равносильно удалению каждой строки, в которой хотя бы одно значение равно -1.Для
df2
:Вы говорите «сохранить строки, в которых одно
df.a
илиdf.b
не равно -1», что равносильно удалению строк, в которых оба значения равны -1.PS: цепной доступ вроде
df['a'][1] = -1
может доставить вам неприятности. Лучше выработать привычку использовать.loc
и.iloc
.источник
DataFrame.query()
здесь тоже хорошо работает.df.query('a != -1 or b != -1')
,&
и|
сноваand
и сноваor
?and
иor
имеет базовую семантику Python, которую нельзя изменить.&
и|
, с другой стороны, имеют соответствующие специальные методы, которые контролируют их поведение. (В строках запроса, конечно, мы можем применять любой анализ, который нам нравится.)df[True & False]
не удается, ноdf[(True) & (False)]
успешно (не проверено на этом примере)Вы можете использовать query () , то есть:
источник
Немного теории математической логики :
«НЕ а И НЕ b» означает «НЕ (а ИЛИ b)» , поэтому:
«a НЕ -1 И b НЕ -1» эквивалентно «НЕ (а равно -1 ИЛИ b равно -1)» , что противоположно (дополнению) «(а равно -1 ИЛИ b равно -1)» .
Поэтому, если вам нужен прямо противоположный результат, df1 и df2 должны быть такими, как показано ниже:
источник