2014-10-29 246 views
5

我有一個看似簡單的任務。具有2列的數據框:A和B.如果B中的值大於A中的值 - 將這些值替換爲A的值。我曾經通過做df.B[df.B > df.A] = df.A來做到這一點,但是最近的熊貓升級在遇到這種鏈接時開始給出SettingWithCopyWarning分配。官方文件建議使用.loc根據條件替換數據幀列中的值

好的,我說,並通過df.loc[df.B > df.A, 'B'] = df.A做到了,它一切正常,除非B列的所有值爲NaN。然後奇怪的事情發生了:

In [1]: df = pd.DataFrame({'A': [1, 2, 3],'B': [np.NaN, np.NaN, np.NaN]}) 

In [2]: df 
Out[2]: 
    A B 
0 1 NaN 
1 2 NaN 
2 3 NaN 

In [3]: df.loc[df.B > df.A, 'B'] = df.A 

In [4]: df 
Out[4]: 
    A     B 
0 1 -9223372036854775808 
1 2 -9223372036854775808 
2 3 -9223372036854775808 

現在,如果B的元素,甚至一個滿足條件(大於A),然後這一切工作正常:

In [1]: df = pd.DataFrame({'A': [1, 2, 3],'B': [np.NaN, 4, np.NaN]}) 

In [2]: df 
Out[2]: 
    A B 
0 1 NaN 
1 2 4 
2 3 NaN 

In [3]: df.loc[df.B > df.A, 'B'] = df.A 

In [4]: df 
Out[4]: 
    A B 
0 1 NaN 
1 2 2 
2 3 NaN 

但是,如果沒有燒烤元素的滿足,那麼所有NaN小號GET替換-9223372036854775808

In [1]: df = pd.DataFrame({'A':[1,2,3],'B':[np.NaN,1,np.NaN]}) 

In [2]: df 
Out[2]: 
    A B 
0 1 NaN 
1 2 1 
2 3 NaN 

In [3]: df.loc[df.B > df.A, 'B'] = df.A 

In [4]: df 
Out[4]: 
    A     B 
0 1 -9223372036854775808 
1 2     1 
2 3 -9223372036854775808 

這是一個錯誤或功能?我應該怎麼做這個替換?

謝謝!

+1

絕對看起來像一個錯誤,可能是一個好主意,要報告[https://github.com/pydata/pandas/issues](https://github.com/pydata/pandas/issues) – Marius 2014-10-29 00:15:22

回答

7

這是一個buggie,固定here

由於熊貓基本上允許在loc的表達式的右側設置任何東西,因此可能有10多個需要消歧的情況。爲了給你一個想法:

df.loc[lhs, column] = rhs 

其中RHS可以是:list,array,scalar和LHS可能是:slice,tuple,scalar,array

和案件的一小部分,其中需要根據推斷/設定所產生的列D型到rhs。 (這有點複雜)。例如,假設你沒有設置lhs上的所有元素,它是整數,那麼你需要強制浮動。但是,如果你確實設置了所有的元素並且rhs是一個整數,那麼它需要被強制回到整數。

在此該特定情況下,在LHS是一個數組,所以我們通常將試圖強制該LHS到RHS的類型,但這種情況下退化,如果我們有一個不安全的轉換(INT - >浮動)

只需說這是一個缺失的邊緣案例。

相關問題