2013-10-26 14 views
9

多くの場合、大きなデータフレームdfが基本データを保持し、基本データ列で計算された派生データを保持するためにさらに多くの列を作成する必要があります。パンダでlazy_evaluatedデータフレーム列を作成する方法

は私が行うことができますそのようなパンダで:

df['derivative_col1'] = df['basic_col1'] + df['basic_col2'] 
df['derivative_col2'] = df['basic_col1'] * df['basic_col2'] 
.... 
df['derivative_coln'] = func(list_of_basic_cols) 

などパンダを計算し、すべてを一度にすべてのデリバティブの列のメモリを割り当てます。

今私が欲しいのは、派生列の計算とメモリ割り当てを実際の必要な瞬間に延期するための怠惰な評価メカニズムを持つことです。私が発行した場合df['derivative_col2']コマンドは、特定の計算とメモリ割り当てをtrigerますため、Pythonの歩留まり「発電機のような時間/メモリを節約します

df['derivative_col1'] = pandas.lazy_eval(df['basic_col1'] + df['basic_col2']) 
df['derivative_col2'] = pandas.lazy_eval(df['basic_col1'] * df['basic_col2']) 

:ややとしてlazy_eval_columnsを定義します。

だからどうやってパンダにlazy_eval()?どんなヒント/思考/参考文献も大歓迎です。

+0

大きな質問です。しかし、パンダにそんなことがあるかどうかは分かりません。このアイデアは、ビュー内のSQL計算カラムを思い出させます。 –

答えて

8

0.13から(すぐにリリースされます)、このようなことができます。これは、ジェネレータを使用して動的な公式を評価しています。インライン評価を介して割り当てがhere

In [19]: df = DataFrame(randn(5, 2), columns=['a', 'b']) 

In [20]: df 
Out[20]: 
      a   b 
0 -1.949107 -0.763762 
1 -0.382173 -0.970349 
2 0.202116 0.094344 
3 -1.225579 -0.447545 
4 1.739508 -0.400829 

In [21]: formulas = [ ('c','a+b'), ('d', 'a*c')] 

evalを使用して式を評価ジェネレータの作成を参照してください、0.13で追加的な特徴であろう。結果を代入し、結果を返します。

In [22]: def lazy(x, formulas): 
    ....:  for col, f in formulas: 
    ....:   x[col] = x.eval(f) 
    ....:   yield x 
    ....:   
アクションで

In [23]: gen = lazy(df,formulas) 

In [24]: gen.next() 
Out[24]: 
      a   b   c 
0 -1.949107 -0.763762 -2.712869 
1 -0.382173 -0.970349 -1.352522 
2 0.202116 0.094344 0.296459 
3 -1.225579 -0.447545 -1.673123 
4 1.739508 -0.400829 1.338679 

In [25]: gen.next() 
Out[25]: 
      a   b   c   d 
0 -1.949107 -0.763762 -2.712869 5.287670 
1 -0.382173 -0.970349 -1.352522 0.516897 
2 0.202116 0.094344 0.296459 0.059919 
3 -1.225579 -0.447545 -1.673123 2.050545 
4 1.739508 -0.400829 1.338679 2.328644 

だから、そのユーザーが(とないオンデマンド)の評価のために発注決定。理論的にはnumbaがこれをサポートしようとしているので、パンダはevalのバックエンドとしてこれをサポートしています(現在は即時評価にnumexprを使用しています)。

my 2c。

遅延評価はいいですが、Pythonの独自の継続/生成機能を使用することで簡単に達成できます。したがって、可能な限りパンダに組み込むことは非常に難しく、一般的には便利です。

+0

最新のアップデートを入手するには、「数式」と評価機能が必要です。また、df ['lazy_eval_col_x']構文を使ってオンデマンド計算を実行する方法についてもっと知りたいと思います。 – bigbug

5

DataFrameをサブクラス化し、列をpropertyとして追加することができます。例えば、

import pandas as pd 

class LazyFrame(pd.DataFrame): 
    @property 
    def derivative_col1(self): 
     self['derivative_col1'] = result = self['basic_col1'] + self['basic_col2'] 
     return result 

x = LazyFrame({'basic_col1':[1,2,3], 
       'basic_col2':[4,5,6]}) 
print(x) 
# basic_col1 basic_col2 
# 0   1   4 
# 1   2   5 
# 2   3   6 

は(以下、x.derivative_col1介して)プロパティにアクセスLazyFrameで定義されたderivative_col1関数を呼び出します。この関数は、結果を計算し、LazyFrameインスタンスに派生列を追加します。

print(x.derivative_col1) 
# 0 5 
# 1 7 
# 2 9 

print(x) 
# basic_col1 basic_col2 derivative_col1 
# 0   1   4    5 
# 1   2   5    7 
# 2   3   6    9 

注意をあなたは基本的なコラム変更した場合ということ:

x['basic_col1'] *= 10 

を派生列が自動的に更新されませんです

print(x['derivative_col1']) 
# 0 5 
# 1 7 
# 2 9 

ただし、プロパティにアクセスすると、値が再計算されます。

print(x.derivative_col1) 
# 0 14 
# 1 25 
# 2 36 

print(x) 
# basic_col1 basic_col2 derivative_col1 
# 0   10   4    14 
# 1   20   5    25 
# 2   30   6    36