2017-06-21 129 views
4

我有這樣一個數據框以下:選擇和整數索引修改大熊貓數據幀片

df = pd.DataFrame([[1,2],[10,20],[10,2],[1,40]],columns = ['a','b']) 
    a b 
0 1 2 
1 10 20 
2 10 2 
3 1 40 

我要選擇b列,其中a == 1,下面是一個典型的選擇:

df[df.a == 1].b 
    a b 
0 1 2 
3 1 40 

然後我想選擇這個子數據框的第i行,這不是索引爲i的行。還有幾種方法,如下所示:

df[df.a == 1].b.iloc[[1]] 
Output: 
3 40 
Name: b, dtype: int64 

到目前爲止好。問題是當我嘗試修改我到達那裏的值時,實際上這個選擇方法產生了數據幀片段的副本,而不是對象本身。所以我不能在原地進行修改。

test[test.a == 1].b.iloc[[1]] = 3 
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame 

我不知道哪一部分的「複製」的問題在於,由於以下兩個產量同樣的問題:

test.iloc[[3]].b = 3 
test[test.a == 1].b = 3 

所以我的問題是這樣的一個:我怎樣才能改變通過掩碼選擇(有條件地在a列值上)和行選擇(通過子數據幀中的行的等級,而不是其索引值)的值?

回答

2

使用loc與布爾面具,直接通過指數上升:

In[178]: 
df.loc[df.loc[df['a'] == 1,'b'].index[1], 'b'] = 3 
df 

Out[178]: 
    a b 
0 1 2 
1 10 20 
2 10 2 
3 1 3 

所以在這裏我們面膜使用df['a'] == 1東風,這將返回一個布爾值數組,我們掩蓋了DF和選擇單純的列'b'

In[179]: 
df.loc[df['a'] == 1,'b'] 

Out[179]: 
0 2 
3 40 
Name: b, dtype: int64 

然後就直接下標索引:

In[180]: 
df.loc[df['a'] == 1,'b'].index[1] 

Out[180]: 3 

然後,我們可以將此索引標籤傳遞迴頂層loc

test[test.a == 1].b.iloc[[1]] = 3chained indexing這就是爲什麼警告提出。

+0

這很完美,謝謝! – ysearka

+0

這個東西不要鏈接'loc','iloc'調用,你應該合成mask,或者如果你可以直接計算索引標籤,那麼你可以將它傳遞給'loc' – EdChum