2017-10-15 192 views
1

我有一個包含每列(A,B,C)中的值的表。 我想用具有最大值的列的名稱創建另一列(max_col)。因此,如果A列大於B或C,則填充「A」。根據其他列中的最大值填充列(python pandas)

下面的代碼有效,但在很多不同的列可供選擇的情況下,它不是非常「pythonic」或可伸縮的。

import pandas as pd 
import numpy as np 

table = { 'A': [1,2,3,4,5,6], 
      'B':[2,4,1,5,3,8], 
      'C':[3,1,2,4,5,6]} 

df = pd.DataFrame.from_dict(table) 
df['total'] = df.max(axis=1) 
df['max_col'] = np.nan 

df['max_col'] = np.where(df['total'] == df['A'],'A',df['max_col']) 
df['max_col'] = np.where(df['total'] == df['B'],'B',df['max_col']) 
df['max_col'] = np.where(df['total'] == df['C'],'C',df['max_col']) 

df 

此外,該代碼被朝最後一列偏壓被檢查,在第5行的情況下,A和C值是相同的,但「max_col」被填充以「C」,因爲它是最後被檢查。理想情況下,'max_col'在這種情況下會填充'No Max'。

回答

1

使用DataFrame.idxmax獲取最大值的列。

但是,如果有多個最大值,得到的布爾面具與max比較所有值,然後總結True秒 - >True s爲像1 S程序。因此,對於最終的掩碼獲得更大的值,如1

df['max_col'] = np.where(df.eq(df.max(axis=1), axis=0).sum(axis=1) > 1, 
         'No Max', 
         df.idxmax(axis=1)) 
print (df) 
    A B C max_col 
0 1 2 3  C 
1 2 4 1  B 
2 3 1 2  A 
3 4 5 4  B 
4 5 3 5 No Max 
5 6 8 6  B 

詳情:

print (df.eq(df.max(axis=1), axis=0)) 
     A  B  C 
0 False False True 
1 False True False 
2 True False False 
3 False True False 
4 True False True 
5 False True False 

print (df.eq(df.max(axis=1), axis=0).sum(axis=1)) 
0 1 
1 1 
2 1 
3 1 
4 2 
5 1 
dtype: int64 

print (df.idxmax(axis=1)) 
0 C 
1 B 
2 A 
3 B 
4 A 
5 B 
dtype: object 

與numpy的廣播類似的解決方案:

arr = df.values 
mask = (arr == arr.max(axis=1)[:, None]).sum(axis=1) > 1 
df['max_col'] = np.where(mask, 'No Max', df.idxmax(axis=1)) 
print (df) 
    A B C max_col 
0 1 2 3  C 
1 2 4 1  B 
2 3 1 2  A 
3 4 5 4  B 
4 5 3 5 No Max 
5 6 8 6  B 

編輯的評論:

cols = ['A','B'] 
df['max_col'] = np.where(df[cols].eq(df[cols].max(axis=1), axis=0).sum(axis=1) > 1, 
         'No Max', 
         df[cols].idxmax(axis=1)) 
print (df) 
    A B C max_col 
0 1 2 3  B 
1 2 4 1  B 
2 3 1 2  A 
3 4 5 4  B 
4 5 3 5  A 
5 6 8 6  B 
0123:

您可以通過子集過濾列

+0

很好,謝謝你的快速回答。你知道什麼是最好的方法來做比較只有有限的列。比方說,列A,B和C是更大數據框的一部分,我不想與其他列進行比較? – Jelmerd

相關問題