#python #pandas #dataframe #filter
Вопрос:
У меня есть фрейм данных, который выглядит примерно так:
pd.DataFrame({
'A Code': ['123', '234', '345', '234'],
'B Code': ['345', '123', '234', '123'],
'X Code': ['987', '765', '765', '876'],
'Y Code': ['765', '876', '987', '765'],
'H Code': ['AB', 'CD', 'EF', 'AB']
})
A Code B Code X Code Y Code H Code
0 123 345 987 765 AB
1 234 123 765 876 CD
2 345 234 765 987 EF
3 234 123 876 765 GH
И я хочу найти строки , где A Code
или B Code
есть 123
и X Code
или Y Code
есть 765
, или где H Code
есть EF
или GH
.
Я использовал следующее условие:
(
((df[df['A Code'] == '123']) | (df[df['B Code'] == '123']))
amp;
((df[df['X Code'] == '765']) | (df[df['Y Code'] == '765']))
)
|
(df[df['H Code'] == 'EF'])
что работает, но становится очень долгим и грязным.
Есть ли более эффективный способ сделать это?
Ответ №1:
Попробуйте использовать any
mask = (
(df[['A Code', 'B Code']] == '123').any(1)
amp; (df[['X Code', 'Y Code']] == '765').any(1)
) | (df['H Code'].isin(['EF', 'GH']))
print(df[mask])
Ответ №2:
Вы можете использовать .query()
df.query("((`A Code` == '123' or `B Code` == '123') and (`X Code` == '765' or `Y Code` == '765')) or `H Code` in ['EF', 'GH']")
Если значения являются параметрами, вы можете ссылаться на них с помощью @
синтаксиса:
a = '123'
df.query("`A Code` == @a")
Ответ №3:
Вот другой способ, используя Серию для простых совпадений (и отдельную isin
для последнего столбца). Это может оказаться проще написать, когда количество условий увеличивается:
# define single conditions
s = pd.Series(['123','123','765','765'],
index=df.columns[:-1])
df[(df[['A Code', 'B Code']].eq(s).any(1)
amp;df[['X Code', 'Y Code']].eq(s).any(1)
)|df['H Code'].isin(['EF', 'GH'])
]
Ответ №4:
Вы можете попробовать любой из приведенных ниже методов, как вам больше нравится.
import pandas as pd
import time
data = pd.DataFrame({
'A Code': ['123', '234', '345', '234'],
'B Code': ['345', '123', '234', '123'],
'X Code': ['987', '765', '765', '876'],
'Y Code': ['765', '876', '987', '765'],
'H Code': ['AB', 'CD', 'EF', 'AB']})
Вы можете проверить следующие три метода-
Способ1-
a_code_filter = ['123']
b_code_filter = ['123']
x_code_filter = ['765']
y_code_filter = ['765']
h_code_filter = ['EF']
idx_ab = (data['A Code'].isin(a_code_filter)) | (data['B Code'].isin(b_code_filter))
idx_xy = (data['X Code'].isin(x_code_filter)) | (data['Y Code'].isin(y_code_filter))
idx_h = (data['H Code'].isin(h_code_filter))
idx = (idx_ab) amp; (idx_xy) | (idx_h)
method1_data = data[idx]
Способ2-
method2_data = data[
((data['A Code']=='123') | (data['B Code']=='123')) amp; ((data['X Code']=='765') | (data['Y Code']=='765'))
| (data['H Code']=='EF')
]
Способ3-
method3_data = data.query("(`A Code`=='123' or `B Code`=='123') amp; (`X Code`=='765' or `Y Code`=='765') | (`H Code`=='EF')")
Комментарии:
1. Сравнение методов 1 и 2 неверно. В методе 1 вы измеряете только индексирование, в методе 2 создание маски индексирование. Также
query()
производительность зависит от размера кадра данных. Это должен быть самый быстрый метод для фрейма данных с более чем 5k-10k строками.2. Спасибо @AlexanderVolkovsky за разъяснение. Сегодня узнал кое-что новое 🙂 . Соответствующим образом изменил пост.