Як реалізувати "в" і "не в" для панд DataFrame?
Панди пропонує два методи: Series.isin
і DataFrame.isin
для серій і 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
приймає різні типи як вхідні дані. Нижче наведено всі дійсні способи отримання бажаного:
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
Фільтр за МНОГО стовпцями
Іноді вам потрібно буде застосувати чек для членства за допомогою деяких пошукових термінів у кількох стовпцях,
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
.
Процедури панд зазвичай ітеративні при роботі з рядками, оскільки рядкові операції важко векторизувати. Існує безліч доказів, що розуміння списків тут буде швидшим. . Ми вдаємося до 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
що було висвітлено у цій відповіді . numxpr FTW!