在Pandas DataFrame上更新行子集的列值的有效方法?

Ale*_*xSB 5 python pandas

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

简单的例子:

import pandas as pd

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

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

以下代码实现了目标:

df.value[df.name.str.len() == 4 ] = df.value[df.name.str.len() == 4] * 1000
Run Code Online (Sandbox Code Playgroud)

但是,此行在LHS和RHS中两次对整个数据帧进行过滤。我认为这不是最有效的方法。它并没有做到“就地”。

基本上我正在寻找与R data.table':='运算符等效的熊猫:

df[nchar(name) == 4, value := value*1000]
Run Code Online (Sandbox Code Playgroud)

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

df[nchar(name) == 4, value := paste0("short_", as.character(value))]
Run Code Online (Sandbox Code Playgroud)

环境: Python 3.6 Pandas 0.22

提前致谢。

jez*_*ael 5

你需要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
Run Code Online (Sandbox Code Playgroud)

编辑:

更通用的解决方案:

mask = df.name.str.len() == 4
df.loc[mask, 'value'] = df.loc[mask, 'value'] * 1000
Run Code Online (Sandbox Code Playgroud)

或者:

df.update(df.loc[mask, 'value'] * 1000)
Run Code Online (Sandbox Code Playgroud)


jpp*_*jpp 4

这可能是您所需要的:

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

 df.loc[df.name.str.len() == 4, 'value'] = 'short_' + df['value'].astype(str)
Run Code Online (Sandbox Code Playgroud)