2017-03-02 52 views
1

我有一個熊貓數據框。在這個DataFrame中,我想修改一些行的幾列。這些是我嘗試的方法。在熊貓中的行子集中修改多個列DataFrame

df[['finalA', 'finalB']] = df[['A', 'B']] 
exceptions = df.loc[df.normal == False] 

其中用得好好的,但現在我想設置的例外情況:

df.loc[exceptions.index, ['finalA', 'finalB']] = \ 
    df.loc[exceptions.index, ['A_except', 'B_except']] 

不工作。所以我嘗試使用this answer.ix

df.ix[exceptions.index, ['finalA', 'finalB']] = \ 
    df.ix[exceptions.index, ['A_except', 'B_except']] 

哪一個也不行。兩種方法在finalAfinalB中給出了NaN的例外行。

,似乎工作在同一時間做它一列的唯一方法:

df.ix[exceptions.index, 'finalA'] = \ 
    df.ix[exceptions.index, 'A_except'] 
df.ix[exceptions.index, 'finalB'] = \ 
    df.ix[exceptions.index, 'B_except'] 

這是怎麼回事的熊貓嗎?如何避免將值設置爲顯然通過選擇多列來複制的副本?有沒有辦法避免這種代碼重複?

一些更多的思考:它實際上沒有將值設置爲數據幀的副本,它將值設置爲NaN。它實際上將它們覆蓋爲一個新的值。


樣品數據框:

import pandas as pd 
df = pd.DataFrame({'A': [1,2,3,4], 
        'B': [5,6,7,8], 
        'normal': [True, True, False, False], 
        'A_except': [0,0,9,9], 
        'B_except': [0,0,10,10]}) 

結果:

A A_except B B_except normal finalA finalB 
0 1 0   5 0   True 1.0  5.0 
1 2 0   6 0   True 2.0  6.0 
2 3 9   7 10   False NaN  NaN 
3 4 9   8 10   False NaN  NaN 

預期結果:

A A_except B B_except normal finalA finalB 
0 1 0   5 0   True 1  5 
1 2 0   6 0   True 2  6 
2 3 9   7 10   False 9  10 
3 4 9   8 10   False 9  10 

回答

2

您可以對齊重命名列名:

d = {'A_except':'finalA', 'B_except':'finalB'} 
df.loc[exceptions.index, ['finalA', 'finalB']] = \ 
    df.loc[exceptions.index, ['A_except', 'B_except']].rename(columns=d) 

print (df) 
    A A_except B B_except normal finalA finalB 
0 1   0 5   0 True  1  5 
1 2   0 6   0 True  2  6 
2 3   9 7  10 False  9  10 
3 4   9 8  10 False  9  10 

另一種解決方案是輸出轉換爲numpy array,但列不對齊:

df.loc[exceptions.index, ['finalA', 'finalB']] = \ 
    df.loc[exceptions.index, ['A_except', 'B_except']].values 

print (df) 
    A A_except B B_except normal finalA finalB 
0 1   0 5   0 True  1  5 
1 2   0 6   0 True  2  6 
2 3   9 7  10 False  9  10 
3 4   9 8  10 False  9  10 
1

如果您查看公式的兩邊,你會發現,列不同。熊貓考慮到列的標籤,並且因爲它們不匹配,所以不會插入該值。

它適用於單個列,因爲這樣您將提取一個Series,然後列標籤不再適用。

一個快速的解決辦法是簡單地剝離數據幀,以裸陣列,那麼無論是locix方法工作:

df.loc[exceptions.index, ['finalA', 'finalB']] = 
    df.loc[exceptions.index, ['A_except', 'B_except']].values 

但請記住,這樣做將消除熊貓嘗試匹配列,索引標籤,它基本上是一個'硬'插入。因此,這使得您作爲用戶負責正確對齊。在這種情況下哪個不是問題,但是一般情況下需要注意的事情。