我有一个 pandas 列,其中有一些字符串。我想将相似的字符串分组,并替换为它们的类别。在我的真实示例中,我有 6 个不同的字符串,我想用 3 个不同的字符串替换它们的类别。
我找到了这个答案,了解如何在replace()函数中使用将许多值映射到1,所以我尝试扩展一些答案来为多个组进行多对1映射,但是并非我的所有值都是正确的改变了,我不知道为什么。
举个例子:
df1 = pd.DataFrame({'col1':['foo', 'foo too', 'bar', 'BAR', 'bar ii']})
col1
0 foo
1 foo too
2 bar
3 BAR
4 bar ii
从其中一个答案来看,您似乎可以使用“|”如果您使用正则表达式来分隔不同的关键选项,所以我这样做如下:
df1['col1'].replace({'foo|foo too' : 'Foo',
'bar|BAR|bar ii' : 'Bar'}, regex=True)
它转换了我的大部分字符串,但不是全部:
col1
0 Foo
1 Foo too
2 Bar
3 Bar
4 Bar ii
从这个例子中,我猜想与空格有关?尽管在我的实际示例中,一些带空格的字符串确实被正确替换,所以我不确定。任何关于为什么这不起作用/我如何实现我所追求的目标的帮助将不胜感激
您必须精心设计正则表达式,以确保另一个模式的子字符串不会出现在较长字符串之前。
这意味着
foo|foo too
将在 foo
之前匹配 foo to
。因此,应该使用foo to|foo
。
df1['col1'].replace({'foo too|foo' : 'Foo',
'bar ii|BAR|bar' : 'Bar'}, regex=True)
输出:
0 Foo
1 Foo
2 Bar
3 Bar
4 Bar
Name: col1, dtype: object
确保较长的单词始终首先出现的通用方法是对字符串进行排序:
import re
motifs = {'Foo': ['foo', 'foo too'],
'Bar': ['bar', 'BAR', 'bar ii'],
}
dic = {'|'.join(map(re.escape, sorted(lst, key=lambda x: -len(x)))) : k
for k, lst in motifs.items()}
df1['col1'].replace(dic, regex=True)
请注意,这仅适用于简单的字符串,不一定适用于更复杂的正则表达式,较短的正则表达式比较长的正则表达式可以匹配更通用的字符串。