首页 > 解决方案 > 在 pandas 中类似地基于字符串创建集群

问题描述

我有一个大约 200-300k 的名字列表

例如。

姓名1 名称2
雷文先生 亚历克斯
房地美 凯文
格雷小姐 摩恩
詹姆士 谢恩
新文 弗雷
博尔特 麦凯
艾伦博士 亚当斯
阿尔斯雷 斯洛特小姐

Names1 应该与 Names2 的每个值进行比较,然后我的 pandas 代码应该创建不同的集群,如 cluster-1、Cluster-2、Cluster-3 等。在这些集群中应该有一个相似名称的列表(删除敬语前缀或后缀)同样大于 90%

例如。

集群 1 集群 2 集群 3
弗雷 雷文 摩恩
灰色的 凯文 新文

有没有办法在熊猫中做到这一点?

标签: pandasdataframecluster-analysis

解决方案


基于此相似度指标的示例代码:

import pandas as pd
from difflib import SequenceMatcher
import numpy as np
import re

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

def remove_prefix(s):
    return re.split('\.| |_|-', s)[-1]

# Mimic dataframe
d = {'Names1': ['Mr.Reven', 'Freddie', 'Miss.Grey', 'James', 'Neoveeen', 'Boult', 'Dr.Alen', 'Alsray'], 
     'Names2': ['Alex', 'Keven', 'Moeen', 'Shayne', 'Frey', 'mcKay', 'Adames', 'Miss. Slout']}
df = pd.DataFrame(d)

# Get two list names with remove prefix
remove_prefix_fv = np.vectorize(remove_prefix)
names1 = remove_prefix_fv(df['Names1'].to_numpy())
names2 = remove_prefix_fv(df['Names2'].to_numpy())

# Get similarity scores for each pairs between Names1 and Names2
similar_fv = np.vectorize(similar)
scores = similar_fv(names1[:, np.newaxis], names2)

# Filter out the pairs above the threshold
threshold = 0.7
ind = np.where(scores >= threshold)

# Cluster the Names2 elements with same Names1 element
uc = np.unique(ind[0])
cd = {"Cluster-" + str(i): [names1[uc[i]]] + list(names2[ind[1][np.where(ind[0] == uc[i])[0]]]) for i in range(len(uc))}

# Build the dataframe
cdf = pd.DataFrame(cd)
print(cdf)

输出:

  Cluster-0 Cluster-1 Cluster-2 Cluster-3
0     Reven      Grey     James      Alen
1     Keven      Frey    Adames      Alex

推荐阅读