Как реализовать 'in' и 'not in' для pandas DataFrame?
Pandas предлагает два метода: _1 _ strong> и DataFrame.isin
для Series и DataFrames соответственно.
Фильтр DataFrame на основе ОДНОГО столбца (также относится к серии)
Наиболее распространенный сценарий - применение условия isin
к определенному столбцу для фильтрации строк в DataFrame.
df = pd.DataFrame({'countries': ['US', 'UK', 'Germany', np.nan, 'China']})
df
countries
0 US
1 UK
2 Germany
3 China
c1 = ['UK', 'China'] # list
c2 = {'Germany'} # set
c3 = pd.Series(['China', 'US']) # Series
c4 = np.array(['US', 'UK']) # array
Series.isin
accepts various types as inputs. The following are all valid ways of getting what you want:
df['countries'].isin(c1)
0 False
1 True
2 False
3 False
4 True
Name: countries, dtype: bool
# `in` operation
df[df['countries'].isin(c1)]
countries
1 UK
4 China
# `not in` operation
df[~df['countries'].isin(c1)]
countries
0 US
2 Germany
3 NaN
# Filter with `set` (tuples work too)
df[df['countries'].isin(c2)]
countries
2 Germany
# Filter with another Series
df[df['countries'].isin(c3)]
countries
0 US
4 China
# Filter with array
df[df['countries'].isin(c4)]
countries
0 US
1 UK
Фильтр по МНОГИМ столбцам
Sometimes, you will want to apply an 'in' membership check with some search terms over multiple columns,
df2 = pd.DataFrame({
'A': ['x', 'y', 'z', 'q'], 'B': ['w', 'a', np.nan, 'x'], 'C': np.arange(4)})
df2
A B C
0 x w 0
1 y a 1
2 z NaN 2
3 q x 3
c1 = ['x', 'w', 'p']
Чтобы применить условие isin
к обоим столбцам «A» и «B», используйте DataFrame.isin
:
df2[['A', 'B']].isin(c1)
A B
0 True True
1 False False
2 False False
3 False True
Отсюда, чтобы сохранить строки, в которых хотя бы один столбец равен True
, мы можем использовать any
вдоль первой оси:
df2[['A', 'B']].isin(c1).any(axis=1)
0 True
1 False
2 False
3 True
dtype: bool
df2[df2[['A', 'B']].isin(c1).any(axis=1)]
A B C
0 x w 0
3 q x 3
Обратите внимание: если вы хотите выполнить поиск в каждом столбце, вы просто пропустите шаг выбора столбца и выполните
df2.isin(c1).any(axis=1)
Аналогичным образом, чтобы сохранить строки, в которых ВСЕ столбцы равны True
, используйте all
так же, как и раньше.
df2[df2[['A', 'B']].isin(c1).all(axis=1)]
A B C
0 x w 0
Примечательные упоминания: numpy.isin
, query
, понимание списка (строковые данные)
В дополнение к методам, описанным выше, вы также можете использовать эквивалент numpy: numpy.isin
.
# `in` operation
df[np.isin(df['countries'], c1)]
countries
1 UK
4 China
# `not in` operation
df[np.isin(df['countries'], c1, invert=True)]
countries
0 US
2 Germany
3 NaN
Почему стоит задуматься? Функции NumPy обычно немного быстрее, чем их эквиваленты в пандах, из-за меньших накладных расходов. Поскольку это поэлементная операция, которая не зависит от выравнивания индекса, очень мало ситуаций, когда этот метод не подходит для замены isin
pandas.
Подпрограммы Pandas обычно итеративны при работе со строками, потому что операции со строками сложно векторизовать. Есть много свидетельств того, что понимание списков здесь будет быстрее.. Мы прибегаем к in
проверке сейчас.
c1_set = set(c1) # Using `in` with `sets` is a constant time operation...
# This doesn't matter for pandas because the implementation differs.
# `in` operation
df[[x in c1_set for x in df['countries']]]
countries
1 UK
4 China
# `not in` operation
df[[x not in c1_set for x in df['countries']]]
countries
0 US
2 Germany
3 NaN
Однако его гораздо сложнее указать, поэтому не используйте его, если не знаете, что делаете.
Наконец, есть также DataFrame.query
, который был рассмотрен в этом ответе. numexpr FTW!
person
cs95
schedule
07.04.2019
~
было добавлено в качестве редактирования в 2019 году. . - person Trenton McKinney   schedule 27.12.2020