2017-03-26 5 views
1

をスピードアップ:パンダforeachの行乗算 - 私はEXTREM遅いコードを有する

Aデータフレームは、約2,000,000行2列(V1、V2)とマルチインデックス(日付とID)とtmpと呼ばれます。

     V1 V2 
Date   ID 
2000-01-01 1  0.3 0.1 
2000-01-01 2  0.3 0.1 
2000-01-02 1  0.1 0.1 
     ..... 

refは250列

と周り5.000行が含まれてい
 C1 C2 ... C250 
ID 
1  0.2 0.3 ... 0.1 
2  1.2 1.3 ... 0.0 

期待される結果は次の形式を持っている必要があります。

sum1 = pd.DataFrame(0, index=idx1, columns=idx2) 
    sum2 = pd.DataFrame(0, index=idx1, columns=idx2) 

    def gen(row): 
     i1 = row.name[0] # date 
     i2 = row.name[1] # id 

     sum1.loc[i1] += ref.loc[i2] * row['V1'] 
     sum2.loc[i1] += ref.loc[i2] * row['V2'] 

    tmp.apply(gen , axis=1) 

  C1 C2 ... C250 
Date 
2000-01-01 xx xx ... xx 

私はそれを試してみました

はこれをスピードアップすることは可能です - 私はCythonでそれを試みたが、3時間後にアプリを殺してきた...

+0

サンプルデータを追加できますか? – jezrael

答えて

0

私はあなたがしてreset_indexによってMultiIndexのレベルidを削除し、mulが必要だと思う:

tmp = pd.DataFrame({'date':pd.date_range('2000-01-01', periods=3), 
        'id':[1,2,1], 
        'V1':[.3,.3,.1], 
        'V2':[.1,.1,.1]}).set_index(['date','id']) 
print (tmp) 
       V1 V2 
date  id   
2000-01-01 1 0.3 0.1 
2000-01-02 2 0.3 0.1 
2000-01-03 1 0.1 0.1 

ref = pd.DataFrame({'C1':[.2,1.2],'C2':[.3,1.3], 'C250':[.1,0.0]}, index=[1,2]) 
ref.index.name = 'id' 
print (ref) 
    C1 C2 C250 
id     
1 0.2 0.3 0.1 
2 1.2 1.3 0.0 

sum1 = ref.mul(tmp['V1'], axis=0).reset_index(level=1, drop=True) 
sum2 = ref.mul(tmp['V2'], axis=0).reset_index(level=1, drop=True) 
print (sum1) 
       C1 C2 C250 
date       
2000-01-01 0.06 0.09 0.03 
2000-01-02 0.36 0.39 0.00 
2000-01-03 0.02 0.03 0.01 

print (sum2) 
       C1 C2 C250 
date       
2000-01-01 0.02 0.03 0.01 
2000-01-02 0.12 0.13 0.00 
2000-01-03 0.02 0.03 0.01 

、その後、もし必要sum列:

sum1 = ref.mul(tmp['V1'], axis=0).reset_index(level=1, drop=True).sum(axis=1).to_frame('SUM') 
sum2 = ref.mul(tmp['V2'], axis=0).reset_index(level=1, drop=True).sum(axis=1).to_frame('SUM') 
print (sum1) 
      SUM 
date    
2000-01-01 0.18 
2000-01-02 0.75 
2000-01-03 0.06 

print (sum2) 
      SUM 
date    
2000-01-01 0.06 
2000-01-02 0.25 
2000-01-03 0.06 
+0

私は以下を受け取ります:ValueError:レベルが指定されておらず、重複しない名前で結合できません。私はそれをgen関数の中で呼び出す必要がありますか? – Roby

+0

'apply'は非常に遅いと思っています、問題はテストデータであるのか、それとも本当ですか?私は答えにテストデータを追加します。 – jezrael

+0

ありがとうございます、インデックスの名前は異なっていました – Roby

関連する問題