У мене є сценарій, коли користувач хоче застосувати кілька фільтрів до об'єкта Pandas DataFrame або Series. По суті, я хочу ефективно зв'язати купу фільтруючих (порівняльних операцій) разом, які задаються користувачем під час виконання.
Фільтри повинні бути добавками (але кожен застосований повинен звужувати результати).
Зараз я використовую, reindex()але це створює новий об'єкт кожного разу і копіює базові дані (якщо я правильно розумію документацію). Отже, це може бути дійсно неефективним при фільтрації великої серії або DataFrame.
Я маю в виду , що використання apply(), map()або що - щось подібне може бути краще. Я досить новачок у Pandas, хоча так усе ще намагаюся обернути голову навколо всього.
TL; DR
Я хочу взяти словник наступної форми і застосувати кожну операцію до заданого об'єкта Series та повернути об’єкт серії «відфільтрований».
relops = {'>=': [1], '<=': [1]}
Довгий приклад
Почну з прикладу того, що я маю на даний момент, і просто фільтрую один об’єкт Series. Нижче наведена функція, яку я зараз використовую:
def apply_relops(series, relops):
"""
Pass dictionary of relational operators to perform on given series object
"""
for op, vals in relops.iteritems():
op_func = ops[op]
for val in vals:
filtered = op_func(series, val)
series = series.reindex(series[filtered])
return series
Користувач надає словник з операціями, які хоче виконати:
>>> df = pandas.DataFrame({'col1': [0, 1, 2], 'col2': [10, 11, 12]})
>>> print df
>>> print df
col1 col2
0 0 10
1 1 11
2 2 12
>>> from operator import le, ge
>>> ops ={'>=': ge, '<=': le}
>>> apply_relops(df['col1'], {'>=': [1]})
col1
1 1
2 2
Name: col1
>>> apply_relops(df['col1'], relops = {'>=': [1], '<=': [1]})
col1
1 1
Name: col1
Знову ж таки, «проблема» мого вищезазначеного підходу полягає в тому, що, на мою думку, існує велика кількість непотрібних копій даних для кроків між проміжками.
Також я хотів би розширити це, щоб словник, який було передано, міг включати стовпці для оператора та фільтрувати цілий DataFrame на основі вхідного словника. Однак я припускаю, що всі роботи для цієї серії можуть бути легко розширені до DataFrame.
df.queryі pd.evalздається, що добре підходить для вашого випадку використання. Для отримання інформації про pd.eval()сімейство функцій, їх особливості та випадки використання, будь ласка, відвідайте Динамічну оцінку вираження в пандах за допомогою pd.eval () .