2017-01-27 9 views
2

私は4つのカラムに 'A'、 'B'、 'C​​'、 'D'という4つのカラムを持ち、numpy ufuncsを使用してパンダのデータフレームを変更

  Letter A B C D   max 
12063289  D 5 9 0 39    0 
12063290  D 3 25 0 79    0 
12063291  B 0 232 0 0    0 
12063292  A 351 0 0 0    0 
12063293  D 0 0 0 394    0 

文字列の値に基づいて、他の3つの列の最大値を計算したいと思います。

  Letter A B C D   max 
12063289  D 5 9 0 39    9 
12063290  D 3 25 0 79    25 
12063291  B 0 232 0 16    16 
12063292  A 351 0 200 0    200 
12063293  D 0 0 0 394    0 

は、上記のデータを変数DFに格納されて、私は次の操作を実行しようとしていると言う:

import numpy as np 
import pandas as pd 

columns = {'A':['B','C','D'], 
      'B':['A','C','D'], 
      'C':['A','B','D'], 
      'D':['A','B','C']} 
for letter in ['A', 'B', 'C', 'D']: 
    mask = df.loc[df['Letter']==letter] 
    np.max(df[mask][columns[letter]], out=df[mask]['max']) 

私は基本的にマスクされたデータフレームの唯一の関連する列に作用することが最大の機能が欲しいですそして、最後の行に文句バック正確に正しい位置が、パンダの元のデータフレーム(DF)の「最大」欄への書き込み:

ValueError: Must pass DataFrame with boolean values only 

質問は、私がTHOS正確にターゲットにはどうすればよいですeセルは不要なスペースを使わないためにmax()関数の出力を受け取ります(私はapply関数でこれを行うことができますが、それは私が持っていない膨大な量のスペースを占有します)。

+0

だから、 'Letter'は、各行からの最大のもののIDを持っていますか? – Divakar

+0

'Letter'は、各行の最大値を計算するのに関係のない列のIDを持ちます。最初の行で 'Letter'が 'D'ならば、その列の最大値は列 'A'、 'B'、 'C​​'から計算されるべきです。 – tobsecret

答えて

1

apply

cols = list('ABCD') 
df.apply(lambda x: x.loc[cols].drop(x.Letter).max(), 1) 

12063289  9 
12063290  25 
12063291  16 
12063292 200 
12063293  0 
dtype: int64 

​​query + groupby

d1 = df.set_index(
    'Letter', append=True 
)[list('ABCD')].rename_axis('Col', 1).stack().to_frame('value') 
d1.query('Letter != Col').groupby(level=0).value.max() 

12063289  9 
12063290  25 
12063291  16 
12063292 200 
12063293  0 
dtype: int64 
+0

あなたの返事をありがとう、df.applyソリューションは私の素朴なソリューションと比較してメモリ使用量を半減させます。しかし、元のデータフレームの約8倍のサイズを使用しています。提供した2つのソリューションのうち最初のものを使用すると、np.maxのout =パラメータで改善する方法はありますか? – tobsecret

関連する問題