用一个值替换 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 替换多个子字符串值

PB中取字符串子串的函数是啥

PB中取字符串子串的函数是啥

如果系列的值包含pandas中的特定字符集,则替换后续字符

用字典值替换 Pandas Dataframe 中的部分字符串

带有字符串子字符串的SwiftUI 5.5初始化数组? [关闭]