Повторное подмножество вашего фрейма данных стоит дорого. Повторное копирование вашего фрейма данных также может быть дорогостоящим. Это также дорого предварительно рассчитать большое количество логических масок. Хитрая часть находит способ применить маски лениво в петле for
.
Хотя приведенное ниже функциональное решение может показаться некрасивым, оно решает вышеуказанные проблемы. Идея состоит в том, чтобы итеративно комбинировать булеву маску с агрегированной маской. Проверьте в своем цикле, имеет ли ваша mask все значения False
, а не пустой ли фрейм данных. Примените совокупную маску один раз в конце вашей логики:
from operator import methodcaller
def filter_df(df):
masks = [('somecolumn', 'gt', 2),
('someother', 'eq', 2),
('all', 'le', 10)]
agg_mask = np.ones(len(df.index)).astype(bool) # "all True" mask
for col, op, val in masks:
mask = methodcaller(op, val)(df[col])
agg_mask = agg_mask & mask
if not agg_mask.any():
return df[agg_mask]
return df[agg_mask]
Примечание для этого решения Операторы сравнения рядов, такие как >
, ==
, <=
, имеют функциональные эквиваленты pd.Series.gt
, pd.Series.eq
, pd.Series.le
.