python将替换字符串中的单词

python将替换字符串中的单词,python,pandas,Python,Pandas,给定如下数据帧: 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']['

给定如下数据帧:

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')
它不起作用。我想知道如何解决这个问题

通过
掩码设置值的解决方案

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
编辑1:

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

#[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
编辑1:

最好是更改条件-如果需要最快的解决方案,请添加
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)

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

df.C = np.where(df.B == 'b', 'no', df.C)
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


时间安排

非常感谢。事实上,我的情况比我所展示的有点困难。我将尝试您首先介绍的方法。应该不需要使用
df.C.replace
。当
df.B.values=='B'
时,我们将使
df.C
no
。。。替换在逻辑上不需要时会使用多余的cpu。事实上,在原始数据帧C中是一列字符串,每个值都包含特定的字,如“是”或“否”。例如“是的,它是”@natsuapo-我正在考虑更好的解决方案-检查上次编辑。@mkheifetz-hmm,所以需要
df['C']=df['C'].str.replace(r“\ba\b”,”)
,它被称为单词边界谢谢。我也会尝试
在哪里