Як реалізувати "в" і "не в" для панд 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!