在 3 个 DataFrame 列中识别略有不同的唯一可识别通用名称的算法
Posted
技术标签:
【中文标题】在 3 个 DataFrame 列中识别略有不同的唯一可识别通用名称的算法【英文标题】:Algo to identify slightly different uniquely identifiable common names in 3 DataFrame columns 【发布时间】:2021-06-15 08:39:16 【问题描述】:示例DataFrame
df
有 3 列来识别任何给定的人,即name
、nick_name
、initials
。它们在指定方式上可能略有不同,但同时查看三列可以克服这些差异并将给定人员的所有行分开,并为每个人使用单个值规范化这 3 列。
>>> import pandas as pd
>>> df = pd.DataFrame('ID':range(9), 'name':['Theodore', 'Thomas', 'Theodore', 'Christian', 'Theodore', 'Theodore R', 'Thomas', 'Tomas', 'Cristian'], 'nick_name':['Tedy', 'Tom', 'Ted', 'Chris', 'Ted', 'Ted', 'Tommy', 'Tom', 'Chris'], 'initials':['TR', 'Tb', 'TRo', 'CS', 'TR', 'TR', 'tb', 'TB', 'CS'])
>>> df
ID name nick_name initials
0 0 Theodore Tedy TR
1 1 Thomas Tom Tb
2 2 Theodore Ted TRo
3 3 Christian Chris CS
4 4 Theodore Ted TR
5 5 Theodore R Ted TR
6 6 Thomas Tommy tb
7 7 Tomas Tom TB
8 8 Cristian Chris CS
在这种情况下,所需的输出如下:
ID name nick_name initials
0 0 Theodore Ted TR
1 1 Thomas Tom TB
2 2 Theodore Ted TR
3 3 Christian Chris CS
4 4 Theodore Ted TR
5 5 Theodore Ted TR
6 6 Thomas Tom TB
7 7 Thomas Tom TB
8 8 Christian Chris CS
公共值可以是任何东西,只要它被标准化为相同的值。例如,name
是 Theodore
或 Theodore R
- 都可以。
我的实际DataFrame
大约有 4000 行。有人可以帮助指定最佳算法来做到这一点。
【问题讨论】:
【参考方案1】:您需要使用 Levenshtein 距离来识别相似的字符串。一个很好的 Python 包是 fuzzywuzzy。下面我使用基本的字典方法将相似的行收集在一起,然后用指定的主行覆盖每个块。请注意,这会留下一个包含许多重复行的 CSV,我不知道这是否是您想要的,但如果不是,那么很容易将重复项取出。
import pandas as pd
from itertools import chain
from fuzzywuzzy import fuzz
def cluster_rows(df):
row_clusters =
threshold = 90
name_rows = list(df.iterrows())
for i, nr in name_rows:
name = nr['name']
new_cluster = True
for other in row_clusters.keys():
if fuzz.ratio(name, other) >= threshold:
row_clusters[other].append(nr)
new_cluster = False
if new_cluster:
row_clusters[name] = [nr]
return row_clusters
def normalize_rows(row_clusters):
for name in row_clusters:
master = row_clusters[name][0]
for row in row_clusters[name][1:]:
for key in row.keys():
row[key] = master[key]
return row_clusters
if __name__ == '__main__':
df = pd.read_csv('names.csv')
rc = cluster_rows(df)
normalized = normalize_rows(rc)
pd.DataFrame(chain(*normalized.values())).to_csv('norm-names.csv')
【讨论】:
以上是关于在 3 个 DataFrame 列中识别略有不同的唯一可识别通用名称的算法的主要内容,如果未能解决你的问题,请参考以下文章
从 pandas DataFrame 中的列中提取 JSON 数据
如何在同一列中写入两个不同变量值的excel/pandas Dataframe
通过从每一行的不同列中选择一个元素,从 Pandas DataFrame 创建一个系列