【问题标题】:pandas dataframe: replace (standalone) substring in cell based on dictpandas dataframe:根据dict替换单元格中的(独立)子字符串
【发布时间】:2020-12-22 00:36:28
【问题描述】:

我想知道社区中是否有人可以提供以下帮助:

旨在正则表达式替换熊猫数据帧中的子字符串(基于我作为参数传递的字典)。虽然 key:value 替换应该只发生,但如果 dict key 被发现为独立的子字符串(而不是单词的一部分)。通过独立子字符串,我的意思是它在空格之后开始

e.x:

mapping = {

   "sweatshirt":"sweat_shirt",
   "sweat shirt":"sweat_shirt",
   "shirt":"shirts"

}

df = pd.DataFrame([
         ["men sweatshirt"]
         ["men sweat shirt"]
         ["yellow shirt"]
       ])

df = df.replace(mapping,regex=True)

预期结果: 运动衫中的子字符串“衬衫”不应替换为“衬衫”,因为值是另一个字符串的一部分,而不是独立值(\b)

注意: 我传递的字典相当长,所以理想情况下有一种方法可以将独立要求 (\b) 作为我传递给 df.replace(dict, regex=True)

的字典的一部分

先谢谢

【问题讨论】:

  • 除了在映射中包含空格外,使用 df = df.apply(lambda x: ' '+x, axis=1).replace(mapping,regex=True).ID.str.strip( )

标签: python regex pandas dictionary


【解决方案1】:

你可以使用

df[0].str.replace(fr"\b(?:{'|'.join([x for x in mapping])})\b", lambda x: mapping[x.group()])

正则表达式看起来像\b(?:sweatshirt|shirt)\b,它将匹配sweatshirt 或shirt 作为整个单词。匹配项将传递给 lambda,并使用 mapping[x.group()] 获取相应的值。

多词搜索词更新

由于您可能需要在 mapping 键中搜索多字词,因此您应该确保最长的搜索词在交替组中排在首位。也就是说,\b(?:abc def|abc)\b 而不是\b(?:abc|abc def)\b。

import pandas as pd

mapping = {
   "sweat shirt": "sweat_shirt",
   "shirt": "shirts"
}

df = pd.DataFrame([
         ["men sweatshirt"],
         ["men sweat shirt"]
       ])
rx = fr"\b(?:{'|'.join(sorted([x for x in mapping],key=len,reverse=True))})\b"
df[0].str.replace(rx, lambda x: mapping[x.group()])

输出:

0     men sweatshirt
1    men sweat_shirt
Name: 0, dtype: object

【讨论】:

  • 想知道您上面的代码是否也考虑了位于单元格值 e.x. 开头的子字符串。 ^衬衫 123?谢谢
  • @Mirko 是的,\b,当后跟一个“单词”字符(数字、字母或_)时,也匹配字符串的开头。
  • 得到了最后一个问题(很抱歉打扰了 Wiktor)。有一些边缘情况,repl。没用。坚持前任。我在最初的帖子中给出了。假设 Id 有一个值为 men sweat shirt 的 df 和以下映射 "sweat shirt: "sweat_shirt", "shirt": "shirts" 。我不确定 key1:value1 或 key2:value2 是否会真正生效。似乎在 9/10 情况下 key1:value1 被替换,但并非总是如此。您能够判断映射中使用的字典是否是从上到下处理的,所以我可以在这些键之前添加带有空格的键?还有其他想法吗?
【解决方案2】:

在您的模式中包含空格! :)

mapping = {

   " sweatshirt":" sweat_shirt",
   " shirt":" shirts"

}

df = ([
         ["men sweatshirt"]
       ])

df = df.replace(mapping,regex=True)

【讨论】:

  • 如果要替换的字符串在开头,则不会替换该字符串。
【解决方案3】:

试试这个代码-

mapping = {

   " sweatshirt":" sweat_shirt",
   " shirt":" shirts"
}

import pandas as pd
df = pd.DataFrame ({'ID':["men sweatshirt", "black shirt"]}
       )

df = df.apply(lambda x: ' '+x, axis=1).replace(mapping,regex=True).ID.str.strip()
print(df)

【讨论】:

    猜你喜欢
    • 2018-10-27
    • 2021-12-24
    • 2016-09-08
    • 2016-08-04
    • 2017-11-01
    • 2016-05-08
    • 2016-11-28
    相关资源
    最近更新 更多