2017-04-22 172 views
2

給定一個數據幀像在單詞:蟒熊貓替換字符串

A B C 
1 a yes 
2 b yes 
3 a no 

我想數據幀改變爲:

A B C 
1 a yes 
2 b no 
3 a no 

這意味着如果塔B具有值「B ',我想將C列更改爲'否'。其中可以用df[df['B']=='b']['C'].str.replace('yes','no')來表示。但使用它本身不會改變數據幀df。即使我嘗試df[df['B']=='b']['C'] = df[df['B']=='b']['C'].str.replace('yes','no')它沒有工作。我想知道如何解決這個問題。

回答

3

解決方案與設定值由mask

df.loc[df.B == 'b', 'C'] = 'no' 
print (df) 
    A B C 
0 1 a yes 
1 2 b no 
2 3 a no 

df['C'] = df['C'].mask(df.B == 'b','no') 
print (df) 
    A B C 
0 1 a yes 
1 2 b no 
2 3 a no 

解決方案與僅更換yes字符串:

df.loc[df.B == 'b', 'C'] = df['C'].replace('yes', 'no') 
print (df) 
    A B C 
0 1 a yes 
1 2 b no 
2 3 a no 

df['C'] = df['C'].mask(df.B == 'b', df['C'].replace('yes', 'no')) 
print (df) 
    A B C 
0 1 a yes 
1 2 b no 
2 3 a no 

差異變df更好地看到:

print (df) 
    A B  C 
0 1 a  yes 
1 2 b  yes 
2 3 b another 
3 4 a  no 

df['C_set'] = df['C'].mask(df.B == 'b','no') 
df['C_replace'] = df['C'].mask(df.B == 'b', df['C'].replace('yes', 'no')) 

print (df) 
    A B  C C_set C_replace 
0 1 a  yes yes  yes 
1 2 b  yes no  no 
2 3 b another no another 
3 4 a  no no  no 

編輯:

在您的解決方案是必要的只添加loc

df.loc[df['B']=='b', 'C'] = df.loc[df['B']=='b', 'C'].str.replace('yes','no') 
print (df) 
    A B  C 
0 1 a  yes 
1 2 b  no 
2 3 b another 
3 4 a  no 

EDIT1:

我真的很好奇的是什麼方法最快:

#[40000 rows x 3 columns] 
df = pd.concat([df]*10000).reset_index(drop=True)  
print (df) 

In [37]: %timeit df.loc[df['B']=='b', 'C'] = df['C'].str.replace('yes','no') 
10 loops, best of 3: 79.5 ms per loop 

In [38]: %timeit df.loc[df['B']=='b', 'C'] = df.loc[df['B']=='b','C'].str.replace('yes','no') 
10 loops, best of 3: 48.4 ms per loop 

In [39]: %timeit df.loc[df['B']=='b', 'C'] = df.loc[df['B']=='b', 'C'].replace('yes','no') 
100 loops, best of 3: 14.1 ms per loop 

In [40]: %timeit df['C'] = df['C'].mask(df.B == 'b', df['C'].replace('yes', 'no')) 
100 loops, best of 3: 10.1 ms per loop 

# piRSquared solution with replace 
In [53]: %timeit df.C = np.where(df.B.values == 'b', df.C.replace('yes', 'no'), df.C.values) 
100 loops, best of 3: 4.74 ms per loop 

EDIT1:

更好的是變化條件 - 如果需要最快解決方案,請添加df.C == 'yes'df.C.values == 'yes'

df.loc[(df.B == 'b') & (df.C == 'yes'), 'C'] = 'no' 

df.C = np.where((df.B.values == 'b') & (df.C.values == 'yes'), 'no', df.C.values) 
+0

感謝。事實上,我的情況比我所說的要難一些。我會嘗試先介紹的方法。 – natsuapo

+0

應該不需要使用'df.C.replace'。當'df.B.values =='b''時,我們將使'df.C''no' ...在邏輯上,替換使用多餘的CPU不需要。 – piRSquared

+0

實際上,在原始數據框中,C是一串字符串,每個值都包含「yes」或「no」等特定字詞。如「是的,它是」 – natsuapo

4

np.where

df.C = np.where(df.B == 'b', 'no', df.C) 

或者

df.C = np.where(df.B.values == 'b', 'no', df.C.values) 

pd.Series.mask

df.C = df.C.mask(df.B == 'b', 'no') 

所有代替改變df和屈服

A B C 
0 1 a yes 
1 2 b no 
2 3 a no 

定時enter image description here

+0

非常感謝。我也會嘗試'哪裏'。 – natsuapo