当 fuzz.WRatio > 90 时对所有计数求和,否则保持不变
Sum all counts when their fuzz.WRatio > 90 otherwise leave intact
我想做的实际上是将所有类似的字符串分组在一列中,然后将它们相加
如果有相似性,则相应计数,否则,保留它们。
有点像这个post。不幸的是,我无法将其应用于我的案例:
不幸的是,我完成了以下步骤:
我写了一个函数来打印每行字符串的所有 fuzz.Wratio,
当每一行从顶部开始线性搜索以检查是否有其他类似的
其余行中的字符串。如果 WRatio > 90,我想对这些行求和
相应的计数。否则,将它们留在那里。
我创建了一个如下所示的测试数据:
test_data=pd.DataFrame({
'name':['Apple.Inc.','apple.inc','APPLE.INC','OMEGA'],
'count':[4,3,2,6]
})
所以我想做的是将结果作为数据框,例如:
result=pd.Dataframe({
'Nname':['Apple.Inc.','OMEGA'],
'Ncount':[9,6]
})
到目前为止,我的函数只给出了每一行的模糊率,
据我了解,
每行与自身比较三次(这里有四行)。
所以我的函数输出看起来像:
pd.Dataframe({
'Nname':['Apple.Inc.','Apple.Inc.','Apple.Inc.','apple.inc',\
'apple.inc','apple.inc'],
'Ncount':[4,4,4,3,3,3],
'FRatio': [100,100,100,100,100,100] })
这只是我用这个测试数据编写的函数的全部输出的一部分。
最后一行 "OMEGA" 会给我一个大约 18 的模糊比率。
我的函数是这样的:
def checkDupTitle2(data):
Nname=[]
Ncount=[]
f_ratio=[]
for i in range(0, len(data)):
current=0
count=0
space=0
for space in range(0, len(data)-1-current):
ratio=fuzz.WRatio(str(data.loc[i]['name']).strip(), \
str(data.loc[current+space]['name']).strip())
Nname.append(str(data.loc[i]['name']).strip())
Ncount.append(str(data.loc[i]['count']).strip())
f_ratio.append(ratio)
df=pd.DataFrame({
'Nname': Nname,
'Ncount': Ncount,
'FRatio': f_ratio
})
return df
所以在 运行 这个函数并得到输出之后,
我试图得到我最终想要的东西。
在这里,我尝试在上面创建的 df 上分组:
output.groupby(output.FRatio>90).sum()
但是这样,我的数据框中仍然需要一个 "name",
我怎样才能决定这个总数的名字,比如这里的 9 个。
"Apple.Inc" 或 "apple.inc" 或 "APPLE.INC"?
或者,我是不是把它弄得太复杂了?
有没有办法一开始就按"name"分组,然后把"Apple.Inc."、"apple.inc"和"APPLE.INC"都一样,那我的问题就解决了。我已经有一段时间了。任何帮助将是高度
赞赏!谢谢!
以下代码使用我的库 RapidFuzz 而不是 FuzzyWuzzy,因为它速度更快,并且它有一个处理方法 extractIndices
,这对这里很有帮助。这个解决方案要快一些,但由于我不经常使用 pandas,我确信还有一些可以改进的地方:)
import pandas as pd
from rapidfuzz import process, utils
def checkDupTitle(data):
values = data.values.tolist()
companies = [company for company, _ in values]
pcompanies = [utils.default_process(company) for company in companies]
counts = [count for _, count in values]
results = []
while companies:
company = companies.pop(0)
pcompany = pcompanies.pop(0)
count = counts.pop(0)
duplicates = process.extractIndices(
pcompany, pcompanies,
processor=None, score_cutoff=90, limit=None)
for (i, _) in sorted(duplicates, reverse=True):
count += counts.pop(i)
del pcompanies[i]
del companies[i]
results.append([company, count])
return pd.DataFrame(results, columns=['Nname','Ncount'])
test_data=pd.DataFrame({
'name':['Apple.Inc.','apple.inc','APPLE.INC','OMEGA'],
'count':[4,3,2,6]
})
checkDupTitle(test_data)
结果是
pd.Dataframe({
'Nname':['Apple.Inc.','OMEGA'],
'Ncount':[9,6]
})
我想做的实际上是将所有类似的字符串分组在一列中,然后将它们相加
如果有相似性,则相应计数,否则,保留它们。
有点像这个post。不幸的是,我无法将其应用于我的案例:
不幸的是,我完成了以下步骤:
我写了一个函数来打印每行字符串的所有 fuzz.Wratio, 当每一行从顶部开始线性搜索以检查是否有其他类似的 其余行中的字符串。如果 WRatio > 90,我想对这些行求和 相应的计数。否则,将它们留在那里。
我创建了一个如下所示的测试数据:
test_data=pd.DataFrame({
'name':['Apple.Inc.','apple.inc','APPLE.INC','OMEGA'],
'count':[4,3,2,6]
})
所以我想做的是将结果作为数据框,例如:
result=pd.Dataframe({
'Nname':['Apple.Inc.','OMEGA'],
'Ncount':[9,6]
})
到目前为止,我的函数只给出了每一行的模糊率, 据我了解, 每行与自身比较三次(这里有四行)。 所以我的函数输出看起来像:
pd.Dataframe({
'Nname':['Apple.Inc.','Apple.Inc.','Apple.Inc.','apple.inc',\
'apple.inc','apple.inc'],
'Ncount':[4,4,4,3,3,3],
'FRatio': [100,100,100,100,100,100] })
这只是我用这个测试数据编写的函数的全部输出的一部分。 最后一行 "OMEGA" 会给我一个大约 18 的模糊比率。
我的函数是这样的:
def checkDupTitle2(data):
Nname=[]
Ncount=[]
f_ratio=[]
for i in range(0, len(data)):
current=0
count=0
space=0
for space in range(0, len(data)-1-current):
ratio=fuzz.WRatio(str(data.loc[i]['name']).strip(), \
str(data.loc[current+space]['name']).strip())
Nname.append(str(data.loc[i]['name']).strip())
Ncount.append(str(data.loc[i]['count']).strip())
f_ratio.append(ratio)
df=pd.DataFrame({
'Nname': Nname,
'Ncount': Ncount,
'FRatio': f_ratio
})
return df
所以在 运行 这个函数并得到输出之后, 我试图得到我最终想要的东西。 在这里,我尝试在上面创建的 df 上分组:
output.groupby(output.FRatio>90).sum()
但是这样,我的数据框中仍然需要一个 "name", 我怎样才能决定这个总数的名字,比如这里的 9 个。 "Apple.Inc" 或 "apple.inc" 或 "APPLE.INC"?
或者,我是不是把它弄得太复杂了? 有没有办法一开始就按"name"分组,然后把"Apple.Inc."、"apple.inc"和"APPLE.INC"都一样,那我的问题就解决了。我已经有一段时间了。任何帮助将是高度 赞赏!谢谢!
以下代码使用我的库 RapidFuzz 而不是 FuzzyWuzzy,因为它速度更快,并且它有一个处理方法 extractIndices
,这对这里很有帮助。这个解决方案要快一些,但由于我不经常使用 pandas,我确信还有一些可以改进的地方:)
import pandas as pd
from rapidfuzz import process, utils
def checkDupTitle(data):
values = data.values.tolist()
companies = [company for company, _ in values]
pcompanies = [utils.default_process(company) for company in companies]
counts = [count for _, count in values]
results = []
while companies:
company = companies.pop(0)
pcompany = pcompanies.pop(0)
count = counts.pop(0)
duplicates = process.extractIndices(
pcompany, pcompanies,
processor=None, score_cutoff=90, limit=None)
for (i, _) in sorted(duplicates, reverse=True):
count += counts.pop(i)
del pcompanies[i]
del companies[i]
results.append([company, count])
return pd.DataFrame(results, columns=['Nname','Ncount'])
test_data=pd.DataFrame({
'name':['Apple.Inc.','apple.inc','APPLE.INC','OMEGA'],
'count':[4,3,2,6]
})
checkDupTitle(test_data)
结果是
pd.Dataframe({
'Nname':['Apple.Inc.','OMEGA'],
'Ncount':[9,6]
})