我有一个名字,姓氏,生日和一些随机变量的数据框架。让我们说它看起来像这样:
BIRTH NAME SURNAME random_value institution
1 1 Luke Skywalker 1 1111
2 1 Luke Skywalker 2 1111
4 2 Leia Organa 3 1211
5 3 Han Solo 7 1342
7 1 Ben Solo 1 1342
8 5 Lando Calrissian 3 1111
9 3 Han Solo 4 1111
10 3 Ham Solo 4 1342
11 1 Luke Wkywalker 9 1111如果在BIRTH、NAME和SURNAME的基础上,名字或姓氏中有一个错误,然后用正确的名字或姓氏替换,我怎么知道呢?
例如,我们看到,在Han Solo上有两个生日的Ham Solo,还有一个生日相同的Ham Solo。我想要这个算法做的是找出Ham是错误的,然后用Han代替它。
如果有两个不同的拼写具有相同的出现次数(对于相同的BIRTH),那么选择哪一个并不重要,只要这个组的所有NAME或SURNAME都是相同的(所以总是Ham或Han,而不是为相同的BIRTH混合)。
所以最终的结果是:
BIRTH NAME SURNAME random_value institution
1 1 Luke Skywalker 1 1111
2 1 Luke Skywalker 2 1111
4 2 Leia Organa 3 1211
5 3 Han Solo 7 1342
7 1 Ben Solo 1 1342
8 5 Lando Calrissian 3 1111
9 3 Han Solo 4 1111
10 3 Han Solo 4 1342
11 1 Luke Skywalker 9 1111有什么自动化的方法吗?我的数据集很大(>3行),手动检查是不可能的。
我可以想象,我们查找所有出生相同的名字和姓氏,然后检查是否有一些只通过字母不同或字母顺序不同的单数异常值(Lukevs Lkue)。当我们发现这样的离群点时,我们就把它替换掉。
我已经在R论坛(如何在数据帧中查找错误并进行替换)上问过这个问题,并得到了回复。我试图直接实现这个方法(由于时间的复杂性,它不幸地失败了)。然后我对其进行了修改,并将其用于较小的子数据帧(按BIRTH分组)。但即使在那时候,我也停止了这个过程,因为R估计这需要超过37个小时,而且这个数字还在上升。
在python中有什么更快的方法来做到这一点吗?如果你能给我任何建议,我将非常感激。
编辑:在评论中指出,有可能,两个同名的人(Jon/John Smit(h))将在同一天出生。在这种情况下,我们要么查看机构列(每个人都应该(但数据集的实际情况可能有点不同)出现8-9次,一个机构编号,3-4次,另一个)。此外,不止一个人共享相同的机构号码。
但是,由于institution可能存在错误数据,我们还可以使用以下推理:如果同一生日的相同全名出现两次以上,我们可以得出结论,它实际上是一个新的人,而不是一个错误(因为同一人不太可能有两种(最多13种)相同的排版),并保留它的名字。
发布于 2017-09-02 17:55:46
首先,我用名字分组出生,并列出由此产生的姓氏。所以我会
['Fkywalker', 'Skywalker', 'Skywalker'] 在此之后,我找出了最常见的名字(天行者),并比较了其他的名字和这个。要查找排字,我计算列文希廷距离。当距离在3以下时,我假设它是一个错误,并像这样更新一个字典:
{'wrong_name' : 'right_name'}然后我对名字做同样的处理。
然后,您有两个替换分词,您可以简单地替换错误的值。
import pandas as pd
import distance
from collections import Counter
dict_SURNAME = dict()
dict_NAME = dict()
def dist(str1, str2):
return distance.levenshtein(str1, str2)
def find_name(namelist, todict):
for names in namelist:
namesorted = Counter(names).most_common()
for name in namesorted[1:]:
if dist(namesorted[0][0], name[0]) < 3:
todict.update({name[0]: namesorted[0][0]})
dfsurname = df1.groupby(['BIRTH', 'NAME']).SURNAME.apply(list).reset_index()
find_name(dfsurname.SURNAME.tolist(), dict_SURNAME)
dfname = df1.groupby(['BIRTH', 'SURNAME']).NAME.apply(list).reset_index()
find_name(dfname.NAME.tolist(), dict_NAME)
print(dict_SURNAME)
print(dict_NAME)
df2 = df1.replace({'NAME': dict_NAME, 'SURNAME': dict_SURNAME})
print(df2)发布于 2020-11-22 12:22:36
库熊猫完全可以做您想做的事情。
它使您有机会找到包含某些排版的重复行,并将它们规范化。
pip install pandas-dedupe下面是一个简短的代码示例
import pandas as pd
import pandas_dedupe
# Data
df = pd.DataFrame({'city':
['Seattle', 'Saettle', 'Seatle', 'Seattle',
'New york', ' New York', 'NewYork',
'London', 'london', 'L ondon',
'Milan', 'Milan', 'Milan', 'Milano',
'Paris', 'paris', 'Paris', 'Paris'],
'country' :
['USA', 'USA', 'USA', 'USA',
'USA', 'USA', 'USA',
'UK', 'UK', 'UK',
'ITA', 'ITA', 'ITA', 'ITA',
'FRA', 'FRA', 'FRA', 'FRA']
})
# Deduplication and canonicalization
dd_df = pandas_dedupe.dedupe_dataframe(
df, # Dataframe to deduplicate
field_properties=['city', 'country'], # List of fields to base deduplication on
canonicalize=['city'], # List of fields to canonicalize (optional)
sample_size=0.8, # Size of sample of records to be labelled
)在本例中,根据city和country列中的行值去复制行,并将变量city的值规范化。
下面是对它的工作原理的简短解释:
pandas-dedupe将要求您将记录样本标记为不同的或重复的。标签后,dedupe将计算出两个或两个以上的记录被复制、去重复和规范化的可能性。
注意: dedupe选择的规范名称是每个集群中最常见的名称。
https://stackoverflow.com/questions/46014718
复制相似问题