2013-08-16 5 views
12

パンダ使用のコードの多くの場所では、Python関数process(row)があります。この関数はDataFrame.iterrows()を超えて使用され、それぞれrowをとり、何らかの処理を行い、究極的にはSeriesとなる値を返します。Python関数を使用してDataFrame行を効率的に処理できますか?

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

  1. をできるだけ効率的に使用するにはどうすればよいでしょうか?
  2. 私たちのコードのほとんどを書き直すことなくそれを行うことはできますか?

この質問のもう1つの側面:このような機能はすべて、数値効率の良い表現に変換できますか?私はnumpy/scipy/Pandasスタックについて多くのことを学んできましたが、真に任意のロジックのために、上記のような遅い純粋なPythonアーキテクチャを使用する必要があることがあります。それは事実ですか?

+0

数学を行う場合は、ベクトル化された操作を行うことができます。文字列やその他の固定サイズのデータ​​型を使用している場合は、数値を数値化してベクタライズした後、行ベースで残りのデータを処理することもできます。 –

答えて

19

軸= 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 

:行単位の演算、パンダapplyを使って最適化されたものでさえ、最も速い解決策ではありません。彼らは確かに多くのは、Python forループより高速ですが、最速ではありません。タイミング操作でそれをテストすることができます。違いがわかります。

いくつかの操作は列指向のものに変換できます(私の例では1つは簡単にdf['a'] + df['b']に変換できます)が、他の操作はできません。特に、分岐、特殊なケース、またはあなたの行で実行する必要がある他のロジックがたくさんある場合。その場合、applyが遅すぎる場合は、"Cython-izing"コードをお勧めします。 CythonはNumPy C APIを使ってうまくいき、最大限のスピードを実現します。

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

+0

'applay'の小さな誤字:) –

+0

@PhillipCloud' axis = 1'に沿って使用することはめったにありません。特定のパフォーマンス上の理由はありますか?アレイの行を賢明に反復する最速の方法ではないでしょうか? –

+0

私はそれが信じています。特に理由はありませんが、私は通常、列指向のデータを扱うため、使用する必要はありません(実際には私の頭の上にはありません)。私はまた、行に沿った操作は、何らかの種類の再構成または 'groupby'操作によってほとんどの時間を避けることができるという疑いを持っていますが、私はそれを裏付ける証拠がなく、ここで間違っているかもしれない私の直感だけです。 –

関連する問題