У меня есть сценарий, когда пользователь хочет применить несколько фильтров к объекту 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 на основе входного словаря. Тем не менее, я предполагаю, что любые работы для Series могут быть легко расширены до DataFrame.