У меня есть сценарий, в котором пользователь хочет применить несколько фильтров к объекту Pandas DataFrame или Series. По сути, я хочу эффективно объединить в цепочку несколько операций фильтрации (операций сравнения), которые задаются пользователем во время выполнения.
Фильтры должны быть аддитивными (то есть каждый применяемый фильтр должен сужать результаты).
В настоящее время я использую, reindex()
но при этом каждый раз создается новый объект и копируются базовые данные (если я правильно понимаю документацию). Таким образом, это может быть действительно неэффективным при фильтрации больших серий или DataFrame.
Я думаю, что лучше использовать apply()
, map()
или что-то подобное. Я новичок в Pandas, поэтому все еще пытаюсь осмыслить все.
TL; DR
Я хочу взять словарь следующей формы и применить каждую операцию к данному объекту Series и вернуть «отфильтрованный» объект 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.