【问题标题】:Python: replace whole word dictionary values in pandas df with dictionary keyPython:用字典键替换熊猫df中的整个单词字典值
【发布时间】:2017-12-28 14:58:59
【问题描述】:

问题: 我需要将 pandas df 列“messages”中的整个单词与字典值进行匹配和替换。 我可以在 df["column"].replace 命令中执行此操作吗?还是我需要找到另一种方法来替换整个单词?

背景: 在我的熊猫数据框中,我有一列包含英文人名键的文本消息,我试图用“名字”的字典值替换。数据框中的特定列如下所示,您可以在其中看到“tommy”作为单个名称。

 tester.df["message"]
          message  
    0                               what do i need to do   
    1                               what do i need to do   
    2  hi tommy thank you for contacting app ...   
    3  hi tommy thank you for contacting  app ...   
    4  hi we are just following up to see if you read... 

字典是根据我从 2000 年人口普查数据库中提取的列表创建的。它有许多不同的名字,可以匹配内联文本,包括“al”或“tom”,如果我不小心,可以在 pandas df 列消息的任何地方放置我的值“名字”:

 import requests 

#import the total name 
r = requests.get('http://deron.meranda.us/data/census-derived-all-first.txt')

#US Census first names
list1= re.findall(r'\n(.*?)\s', r.text, re.DOTALL)


#turn list to string, force lower case
str1 = ', '.join('"{0}"'.format(w) for w in list1)

str1 = ','.join(list1)
str1 = (str1.lower())

#turn into dictionary with "First Name" as value

str1 = dict((el, 'FirstName') for el in str1)

现在我想用 'FirstName' 值替换 DF 列“消息”中与字典键匹配的 整个 单词。不幸的是,当我执行以下操作时,它会替换消息中的文本,它甚至可以匹配“al”或“tom”等短名称。

In [254]: tester["message"].replace(str1, regex = True)
Out[254]: 
0                   wFirstNamet do i neFirstName to do
1                   wFirstNamet do i neFirstName to do
2    hi FirstNameFirstName tFirstName you for conFi...
3    hi FirstNameFirstName tFirstName you for conFi...
4    hi we are just followFirstNameg up to FirstNam...
Name: message, dtype: object

感谢任何帮助匹配和替换整个键的值!

更新/尝试修复 1:尝试添加一些正则表达式功能以仅匹配整个单词**

我尝试为提取的字符串中的每个单词添加一个中断字符,该字典由其构成。不幸的是,单斜杠是有限的单词,它们会变成双斜杠,并且与字典键 -> 值替换不匹配。

#import the total name 
r = requests.get('http://deron.meranda.us/data/census-derived-all-first.txt')
l = requests.get('https://deron.meranda.us/data/popular-last.txt')
#US Census first names
list1= re.findall(r'\n(.*?)\s', r.text, re.DOTALL)

#add regex before

string = 'r"\\'
endstring = '\\b'

list1 = [ string + x + endstring  for x in list1]

#turn list to string, force lower case
str1 = ', '.join('"{0}"'.format(w) for w in list1)

str1 = ','.join(list1)
str1 = (str1.lower())


##if we do print(str1) it shows one backslash 
##turn to list ..but print() doesn't let us have one backlash anymore 

str1 = [x.strip() for x in str1.split(',')]



#turn to dictionary with "firstname"
str1 = dict((el, 'FirstName') for el in str1)

然后当我尝试使用 break 正则表达式匹配和替换更新的字典键时,我得到了一个糟糕的转义

tester["message"].replace(str1, regex = True)

" 回溯(最后一次调用): 错误:错误转义 \j"

这可能是正确的方向,但是反斜杠到双反斜杠的转换似乎很棘手......

【问题讨论】:

  • 如果您不需要在 Python 中执行此操作,可以使用简单的 shell 脚本,例如 this example here

标签: python regex pandas dictionary


【解决方案1】:

首先,您需要准备名称列表,使其与以字符串开头 (^) 或空格 (\s) 开头并后跟空格或结尾的名称相匹配字符串 ($)。然后,您需要确保保留前后元素(通过反向引用)。假设您有一个列表 first_names,其中包含应替换的所有名字:

replacement_dict = {
    r'(^|\s){}($|\s)'.format(name): r'\1FirstName\2'
    for name in first_names
}

让我们看一下正则表达式:

(         # Start group.
  ^|\s    # Match either beginning of string or whitespace.
)         # Close group.
{}        # This is where the actual name will be inserted.
(
  $|\s    # Match either end of string or whitespace.
)

以及替换正则表达式:

\1     # Backreference; whatever was matched by the first group.
FirstName
\2     # Backreference; whatever was matched by the second group.

【讨论】:

  • 嘿,谢谢!这行得通。在这种情况下不必构建字典。
  • 作为一个附带问题,我是否可以保留相同的答案,但也包括一个模糊匹配选项,以防文本中的名称不完美?
  • @Peachazoid 您能否更具体地说明“模糊匹配”和“不完美”的名称是什么意思?或许你可以举个例子?
  • 当然!因此,在我的 df 中,我有一些本来是键的词,但有轻微的含义(例如,“tommmy”而不是“tommy”)。我想使用python中的fuzzy wuzzy包来识别单词是否靠近键并将其替换为值。我正在考虑尝试做类似的事情:stackoverflow.com/questions/34197917/… 但在键值模糊匹配而不是字符串上
猜你喜欢
  • 2018-08-07
  • 2018-07-27
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
  • 2017-06-18
  • 2020-11-30
  • 1970-01-01
  • 2018-01-10
相关资源
最近更新 更多