ユーザーがいくつかのフィルターを Pandas DataFrame または Series オブジェクトに適用したいというシナリオがあります。基本的に、実行時にユーザーが指定した一連のフィルタリング (比較操作) を効率的に連鎖させたいと考えています。
フィルタは追加的である必要があります (つまり、適用されるそれぞれが結果を絞り込む必要があります)。
私は現在使用してreindex()
いますが、これは毎回新しいオブジェクトを作成し、基礎となるデータをコピーします(ドキュメントを正しく理解している場合)。そのため、大きな Series または DataFrame をフィルタリングする場合、これは非常に非効率的です。
apply()
、map()
、または同様のものを使用する方が良いかもしれないと考えています。私はパンダにかなり慣れていないので、まだすべてを理解しようとしています。
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 に簡単に拡張できると想定しています。