Pandas DataFrame 中更新部分行的列值的高效方法?

10

当使用Pandas更新特定子集行的列值时,最好的方法是什么?

简单示例:

import pandas as pd

df = pd.DataFrame({'name' : pd.Series(['Alex', 'John', 'Christopher', 'Dwayne']),
                   'value' : pd.Series([1., 2., 3., 4.])})

目标:根据名称的长度和值列本身的初始值更新value列。

以下行代码实现了此目标:

df.value[df.name.str.len() == 4 ] = df.value[df.name.str.len() == 4] * 1000

然而,这条线路会在左右两侧过滤整个数据表格两次。我认为这不是最有效的方式。并且它没有'原地'执行。

基本上,我正在寻找与R data.table ':='运算符相对应的pandas等效方法:

df[nchar(name) == 4, value := value*1000]

而对于其他类型的操作,比如:

df[nchar(name) == 4, value := paste0("short_", as.character(value))]

环境: Python 3.6 Pandas 0.22

提前致谢。

2个回答

8
你需要使用 loc*=
df.loc[df.name.str.len() == 4, 'value'] *= 1000
print (df)
          name   value
0         Alex  1000.0
1         John  2000.0
2  Christopher     3.0
3       Dwayne     4.0

编辑:

更通用的解决方案:

mask = df.name.str.len() == 4
df.loc[mask, 'value'] = df.loc[mask, 'value'] * 1000

或者:

df.update(df.loc[mask, 'value'] * 1000)

感谢@jezrael的回答。但是,如果这不是像我提出的第二个R案例那样简单的乘法,那该怎么办呢? - AlexSB
嗯,那么可以缓存掩码并使用您的解决方案与 loc 或使用 update - jezrael

4
这可能是你需要的内容:
 df.loc[df.name.str.len() == 4, 'value'] *= 1000

 df.loc[df.name.str.len() == 4, 'value'] = 'short_' + df['value'].astype(str)

谢谢@jp_data_analysis。那个完美地解决了问题。您能否解释一下或指出为什么RHS上的df['value']被行子集过滤?是使用.loc来完成的吗? - AlexSB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接