将具有相似(但略有不同)子字符串的字符串重新映射到相同的结果

2024-04-20 06:21:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧如下:

df = pd.DataFrame({
"group_code": ['111', '111', '111', '111', '111', '111', '111', '222', '222','222', '222', '222', '222'],
"ind_code": ['K M trading', 'K.M trad', 'KM trading LL', 'bill payment', 'pays', 'PayMent', 'Payer', 'Rev12','Rev11','13 rev','Rev13','Rev .!','REV 17']
})

我想对列中的所有值进行分组: 'K M trading', 'K.M trad', 'KM trading LL'作为"KM Trading"。 有人能帮我吗?你知道吗

我试过下面的代码,但不起作用

 def replace_(row):
if 'pay' in row.lower():
    return 'Payment'
if 'rev' in row.lower():
    return 'Rev'
if 'km' in row.lower():
    return 'KM Trade'
else:
return row
df.ind_code = df.ind_code.apply(lambda row : replace_(row))
print(df)

Tags: indfreturnifcoderevlowerreplace
3条回答

您可以构建正则表达式的映射,并使用字典调用Series.replace。你知道吗

mapping = {'pay' : 'Payment', 'rev' : 'Rev', 'km': 'KM Trading'}
for k, v in mapping.items():
    mapping['(?i).*' + r"\.?\s?".join(k) + '.*$'] = mapping.pop(k)

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

0     KM Trading
1     KM Trading
2     KM Trading
3        Payment
4        Payment
5        Payment
6        Payment
7            Rev
8            Rev
9            Rev
10           Rev
11           Rev
12           Rev
Name: ind_code, dtype: object

在哪里

print(mapping)

{'(?i).*k\\.?\\s?m.*$': 'KM Trading',
 '(?i).*p\\.?\\s?a\\.?\\s?y.*$': 'Payment',
 '(?i).*r\\.?\\s?e\\.?\\s?v.*$': 'Rev'}

表示不区分大小写的替换,在要替换的字符之间有可选的句点和空格。你知道吗

您可以尝试使用levenshtein距离来计算两个单词之间的距离。 基本上,这个距离计算从字符串a到字符串b的单字符编辑(插入、删除或替换)的最小数量

例如,您可以使用基本字符串“km trading”,并将其与所有其他字符串进行比较,如果距离低于阈值(如4),则您可以非常确定该字符串是“km trading”的变体。你知道吗

def minimumEditDistance(s1,s2):
    if len(s1) > len(s2):
        s1,s2 = s2,s1
    distances = range(len(s1) + 1)
    for index2,char2 in enumerate(s2):
        newDistances = [index2+1]
        for index1,char1 in enumerate(s1):
            if char1 == char2:
                newDistances.append(distances[index1])
            else:
                newDistances.append(1 + min((distances[index1],
                                             distances[index1+1],
                                             newDistances[-1])))
        distances = newDistances
    return distances[-1]

dist = minimumEditDistance('km trading', 'K.M trad'.lower())
print(dist)

这段代码取自Rosetta代码,该算法很难从纯粹的直觉理解,所以我建议查看一些深入解释该算法的教程。你知道吗

Oren revenge的答案非常棒,这里有一个针对您的具体案例的黑客解决方案(尽管很容易扩展):

for pair in [('km','KM Trading'), ('pay', 'Payment'), ('rev', 'Rev')]:
    df1.ind_code = df1.ind_code.apply(lambda x: pair[1] if pair[0] in re.sub('\.', '', x.lower()).strip() else x)

相关问题 更多 >