用一个值替换 Pandas 系列中的多个子字符串
Posted
技术标签:
【中文标题】用一个值替换 Pandas 系列中的多个子字符串【英文标题】:Replace multiple substrings in a Pandas series with a value 【发布时间】:2018-08-30 23:12:13 【问题描述】:全部,
要替换一个特定列中的一个字符串,我已经这样做了,并且效果很好:
dataUS['sec_type'].str.strip().str.replace("LOCAL","CORP")
我现在想用一个字符串替换多个字符串,比如用"CORP"
替换["LOCAL", "FOREIGN", "HELLO"]
如何让它发挥作用?下面的代码不起作用
dataUS['sec_type'].str.strip().str.replace(["LOCAL", "FOREIGN", "HELLO"], "CORP")
【问题讨论】:
【参考方案1】:replace
可以接受 dict
,我们只是为那些需要替换的值创建一个字典
dataUS['sec_type'].str.strip().replace(dict(zip(["LOCAL", "FOREIGN", "HELLO"], ["CORP"]*3)),regex=True)
字典信息
dict(zip(["LOCAL", "FOREIGN", "HELLO"], ["CORP"]*3))
Out[585]: 'FOREIGN': 'CORP', 'HELLO': 'CORP', 'LOCAL': 'CORP'
您收到错误的原因,
str.replace 与 replace 不同
【讨论】:
试试dict.fromkeys(["LOCAL", "FOREIGN", "HELLO"], 'CORP')
我已经尝试了两种建议的解决方案并得到错误 TypeError: replace() takes at least 3 arguments (2 given)
是的,我也是……我有不同的解决方案
@cᴏʟᴅsᴘᴇᴇᴅ 哈哈喜欢这个,即使你进步了,仍然【参考方案2】:
试试:
dataUS.replace("sec_type": 'LOCAL' : "CORP", 'FOREIGN' : "CORP")
【讨论】:
这比我的解决方案更好,因为它使用了 pandas 本机方法,当我专注于我所知道的 str.replace() 中的问题时,我忽略了它 这不适用于子字符串。你需要pd.Series.str.replace
,而不是pd.Series.replace
。
@jpp 对不起,我不明白
查找pd.Series.replace
[需要精确字符串匹配] 和pd.Series.str.replace
[替换子字符串] 之间的区别。它们是不同的方法,做不同的事情。【参考方案3】:
您可以通过形成 | 分隔的字符串来执行此任务。这是因为pd.Series.str.replace
接受正则表达式:
将系列/索引中出现的模式/正则表达式替换为一些 其他字符串。等价于 str.replace() 或 re.sub()。
这避免了创建字典的需要。
import pandas as pd
df = pd.DataFrame('A': ['LOCAL TEST', 'TEST FOREIGN', 'ANOTHER HELLO', 'NOTHING'])
pattern = '|'.join(['LOCAL', 'FOREIGN', 'HELLO'])
df['A'] = df['A'].str.replace(pattern, 'CORP')
# A
# 0 CORP TEST
# 1 TEST CORP
# 2 ANOTHER CORP
# 3 NOTHING
【讨论】:
您的解决方案最适合我。谢谢你。我也喜欢提出的解决方案(但我认为已被删除) dataUS.replace("sec_type": 'POOL' : "OTHERS", 'ABS' : "OTHERS") 投反对票的人是否愿意提出这种方法的问题? 这对我不起作用,是因为我使用的是 Python 2 吗?您也没有解释它为什么起作用(这将是一个更好的答案),但我推断这是一种正则表达式格式?我不熟悉 Python 3,但我没有看到这里记录:docs.python.org/2/library/string.html#string.replace 这对我有用(python 3.6 / pandas 0.19.2),也许你使用的是旧版本的 pandas 和/或 python。不过,OP 确实接受了它.. 另外,我投了反对票,因为我认为使用 Rakesh 建议的内置 pandas 非常优越(甚至比我自己的答案)【参考方案4】:替换熊猫系列中多个值的功能:
def replace_values(series, to_replace, value):
for i in to_replace:
series = series.str.replace(i, value)
return series
希望这对某人有所帮助
【讨论】:
【参考方案5】:@Rakesh 的答案非常简洁,但不允许使用子字符串。然而,只要稍作改动,它就可以了。
-
使用替换字典,因为它更通用
将关键字参数
regex=True
添加到Series.replace()
(不是Series.str.replace
) 这实际上做了两件事:它将您的替换更改为正则表达式替换,这更强大,但您必须转义特殊字符。请注意这一点。其次,它将使替换对子字符串而不是整个字符串起作用。这真是太酷了!
replacement =
"LOCAL": "CORP",
"FOREIGN": "CORP",
"HELLO": "CORP"
dataUS['sec_type'].replace(replacement, regex=True)
完整代码示例
dataUS = pd.DataFrame('sec_type': ['LOCAL', 'Sample text LOCAL', 'Sample text LOCAL sample FOREIGN'])
replacement =
"LOCAL": "CORP",
"FOREIGN": "CORP",
"HELLO": "CORP"
dataUS['sec_type'].replace(replacement, regex=True)
输出
0 CORP
1 CORP
2 Sample text CORP
3 Sample text CORP sample CORP
Name: sec_type, dtype: object
【讨论】:
这个解决方案比对一列一列使用多个替换调用要慢。【参考方案6】:@JJP 如果您的列表很长,那么答案是一个很好的答案。但是如果你只有两个或三个,那么你可以简单地使用'|'图案内。确保添加regex=True
参数。
显然.str.strip()
不是必需的,但这是一种很好的做法。
import pandas as pd
df = pd.DataFrame('A': ['LOCAL TEST', 'TEST FOREIGN', 'ANOTHER HELLO', 'NOTHING'])
df['A'] = df['A'].str.strip().str.replace("LOCAL|FOREIGN|HELLO", "CORP", regex=True)
输出
A
0 CORP TEST
1 TEST CORP
2 ANOTHER CORP
3 NOTHING
【讨论】:
以上是关于用一个值替换 Pandas 系列中的多个子字符串的主要内容,如果未能解决你的问题,请参考以下文章
用 pandas str.replace 替换多个子字符串值