我有两个不同长度的Pandas数据帧。DF1有大约120万行(只有1列),DF2有大约300000行(只有一列),我正试图从这两个列表中找到类似的项。
DF1的公司名称约占75%,人员约占25%,DF2的情况正好相反,但它们都是字母数字。我想写一个函数,突出显示两个列表中最相似的项目,按分数(或百分比)排序。例如,
Apple -> Apple Inc. (0.95)
Apple -> Applebees (0.68)
Banana Boat -> Banana Bread (0.25)
到目前为止,我已经尝试了两种方法,但都失败了。
方法1:查找两个列表的Jaccard系数。
import numpy as np
from sklearn.metrics import jaccard_similarity_score
jaccard_similarity_score(df_1, df_2)
这不起作用,可能是由于两个数据帧的长度不同,我得到了这个错误:
ValueError:发现样本数不一致的数组
方法2::使用序列匹配
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
然后调用数据帧:
similar(df_1, df_2)
这会导致一个错误:
pandas.index.IndexEngine.get_loc中的pandas/index.pyx(熊猫/指数c:3979)()
pandas.index.IndexEngine.get_loc中的pandas/index.pyx(熊猫/索引:c:3843)()
pandas.hashtable.PyObjectHashTable.get_item中的pandas/hashtable.pyx(pandas/hashtable.c:12265)()
pandas.hashtable.PyObjectHashTable.get_item中的pandas/hashtable.pyx(pandas/哈希表。c:12216)()
KeyError:0
我该如何处理这个问题?
解决方案
我不得不安装distance
模块,因为它比弄清楚如何在这种情况下使用jaccard_similarity_score
更快。我无法用那个函数重新创建你的数字。
安装distance
pip install distance
使用distance
import distance
jd = lambda x, y: 1 - distance.jaccard(x, y)
df_1.head().iloc[:, 0].apply(lambda x: df_2.head().iloc[:, 0].apply(lambda y: jd(x, y)))
head()
为您提供保护。我敢肯定,去掉它们会炸毁你的电脑,因为它会产生一个1.2米X 0.3米的矩阵。
试试这个。我不太确定你最终想要什么。我们可以随着您的清晰度进行调整。
或者用于比较,仅限于处于相同元素位置的项目。
import distance
jd = lambda x, y: 1 - distance.jaccard(x, y)
test_df = pd.concat([df.iloc[:, 0] for df in [df_1, df_2]], axis=1, keys=['one', 'two'])
test_df.apply(lambda x: jd(x[0], x[1]), axis=1)