pandas: несколько условий при индексировании фрейма данных-неожиданное поведение
я фильтрую строки в фрейме данных по значениям в двух столбцах.
по какой-то причине оператор OR ведет себя так, как я ожидал, и оператор будет вести себя и наоборот.
мой тестовый код:
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.
2 ответов
как вы можете видеть, оператор AND отбрасывает каждую строку, в которой по крайней мере один значение равно -1. С другой стороны, оператор OR требует обоих значения должны быть равны -1, чтобы удалить их.
это верно. Помните, что вы пишете условие с точки зрения того, что вы хотите keep, не с точки зрения того, что вы хотите бросить. Для df1
:
df1 = df[(df.a != -1) & (df.b != -1)]
вы говорите: "держите строки, в которых df.a
не -1, а df.b
isn'T -1", что то же самое, что отбрасывать каждую строку, в которой хотя бы одно значение равно -1.
на df2
:
df2 = df[(df.a != -1) | (df.b != -1)]
вы говорите: "держите строки, в которых либо df.a
или df.b
не -1", что то же самое, что и удаление строк, где оба значения равны -1.
PS: прикованный доступ, как df['a'][1] = -1
может доставить вам неприятности. Лучше привыкнуть использовать .loc
и .iloc
.
можно использовать query (), то есть:
df_filtered = df.query('a == 4 & b != 2')