12

Pandas を使用するコードの多くの場所に、いくつかの Python 関数 がありますprocess(row)。その関数は で使用されDataFrame.iterrows()、それぞれをrow受け取り、いくつかの処理を行い、最終的に新しい に収集する値を返しますSeries

この使用パターンは、numpy / Pandas スタックのパフォーマンス上の利点のほとんどを回避していることに気付きました。

  1. この使用パターンを可能な限り効率的にするための最良の方法は何でしょうか?
  2. ほとんどのコードを書き直さずにそれを実行できるでしょうか?

この質問の別の側面: そのような関数はすべて、効率的な表現に変換できますか? numpy / scipy / Pandas スタックについて学ぶことはたくさんありますが、真に任意のロジックについては、上記のような遅い純粋な Python アーキテクチャを使用する必要がある場合があるようです。そうですか?

4

1 に答える 1

20

axis=1 に沿って関数を適用する必要があります。関数は引数として行を受け取り、それが返すものはすべて新しいシリーズ オブジェクトに収集されます

df.apply(you_function, axis=1)

例:

>>> df = pd.DataFrame({'a': np.arange(3),
                       'b': np.random.rand(3)})
>>> df
   a         b
0  0  0.880075
1  1  0.143038
2  2  0.795188
>>> def func(row):
        return row['a'] + row['b']
>>> df.apply(func, axis=1)
0    0.880075
1    1.143038
2    2.795188
dtype: float64

質問の2番目の部分については、 pandas を使用して最適化された行単位の操作でさえapply、最速のソリューションではありません。それらは確かに Python の for ループよりもはるかに高速ですが、最速ではありません。タイミング操作でそれをテストすると、違いがわかります。

一部の操作は列指向の操作に変換できますが (私の例の 1 つは簡単に に変換できますdf['a'] + df['b'])、他の操作は変換できません。特に、行で実行する必要がある分岐、特殊なケース、またはその他のロジックが多数ある場合。その場合、applyが遅すぎる場合は、コードを「Cython 化」することをお勧めします。Cython は NumPy C API と非常にうまく連携し、達成できる最大速度を提供します。

または、numbaを試すことができます。:)

于 2013-08-16T22:23:57.447 に答える