使用Python Pandas和正则表达式在DataFrame中使用字典替换项目。

3

你好,我正在尝试使用Python Pandas中的字典来重新映射数据框,但我需要使用正则表达式使其正常工作。

这是字典的示例:

di_cities = {
"Ain Salah (town)": "Ain Salah"
"Agadez town": "Agadez"
"Bamako city":  "Bamako",
"Birnin Konni town":  "Birni N Konni",
"Konni":  "Birni N Konni",
"Kadunà":  "Kaduna",
"Kaduna (city)":  "Kaduna",
"Kano (city)":  "Kano"
"Matamey":  "Matamey",
"Mopti city":  "Mopti"
"N'guigmi":  "Nguigmi",
"Tunis":  "Tunis",
"Tunis (city)":  "Tunis"
}

我使用这个迭代:
di_cities = {rf"\b{k}\b": v for k, v in di_cities.items()}
df_cities_clean = df.replace(di_cities, regex=True)

如图所示(最终结果),它适用于巴马科、阿加德兹、莫普提和每个单词字符串,但对于任何带括号的字符串都不起作用,在Birnin Konni的情况下会有些混乱。

我正在以类似的方式使用另一个字典,但那里每个字符串都在括号中,{rf"\({k}\)"可以完美地工作。

你能帮我吗?

最终结果


1
尝试使用di_cities = {rf"\b{re.escape(k)}(?:(?<=\w)\b|(?<!\w))": v for k, v in di_cities.items()}。请注意,如果您的字典具有重叠键(即其他键的前缀),则可能无法正常工作。这还假定您的键始终以单词字符开头。 - Wiktor Stribiżew
谢谢Wiktor!对我来说几乎完美!它可以胜任除了Konni之外的所有工作,即重叠键(目前只有这一个),但我已经用一种解决方法解决了。 - Irvine
谢谢您的回复,但我不能从字符串中分离括号,因为我需要规范城市名称的拼写方式:例如,“突尼斯(城市)”->“突尼斯”。当然,我可以通过其他方式得出结果,但使用字典会更容易。 - Irvine
你真的需要在所有列上运行它吗? - Wiktor Stribiżew
1
太好了,下次请在评论中添加@用户名以通知该用户您的反馈。 - Wiktor Stribiżew
显示剩余4条评论
1个回答

1

我建议使用

di_cities = {rf"\b{re.escape(k)}(?:(?<=\w)\b|(?<!\w))": v for k, v in di_cities.items()}

使用这个字典推导式,您可以创建另一个字典,其中键是正则表达式,匹配以单词字符开头的整个单词作为前面的键(即数字、字母、下划线、连接标点符号),如果它们以单词字符结尾,则不会立即跟随另一个单词字符。 如果一个键不以单词字符结尾,例如以标点符号或空格结尾(也许添加.strip()会更安全),则不应用其他边界检查。 rf"\b{re.escape(k)}(?:(?<=\w)\b|(?<!\w))"首先转义[所有特殊的正则表达式元字符]关键字,然后在其前面加上单词边界,(?:(?<=\w)\b|(?<!\w))是一个非捕获组,匹配:
- (?<=\w)\b - 如果前一个字符是单词字符,则匹配一个单词边界((?<!...)是一个正向回顾后发现) - | - 或 - (?<!\w)) - 如果当前位置左侧没有紧挨着的单词字符,则没有进行其他检查(空字符串匹配)((?<!...)是一个负向回顾后发现)。

1
谢谢Wiktor!那个完美地运作了。你的解释也非常清晰。 - Irvine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接