【问题标题】:How can I calculate the Levenshtein distance between all rows in two dataframes and output the Levenshtein score for each pair?如何计算两个数据帧中所有行之间的 Levenshtein 距离并输出每对的 Levenshtein 分数?
【发布时间】:2020-06-16 10:58:23
【问题描述】:

我正在尝试计算两个数据帧(dfa 和 dfb)之间的 Levenshtein 距离,如下所述。

dfa:

Name      Addresss     ID  
Name1a    Address1a    ID1a
Name2a    Address2a    ID2a

dfb:

Name      Addresss      ID  
Name1b    Address1b   ID1b
Name2b    Address2b   ID2b

我了解计算两个字符串之间的距离,但我有点困惑,我怎么能对另一个列做一组列,输出看起来像这样,它显示所有对和分数:

输出:

Name      Name      LevScore
Name1a    Name1b       0.87
Name1a    Name2b       0.45
Name1a    Name3b       0.26
Name2a    Name1b       0.92
Name2a    Name2b       0.67
Name2a    Name3b       0.56
etc

提前致谢!

马内什

【问题讨论】:

  • 您能否更具体地说明您希望如何计算 levScore?
  • 嗨 Narendra,我想计算 dfa 中的每个“名称”和 dfb 中的每个“名称”之间的 Lev 分数,并输出每对的分数以及每个关联的“名称”的列用于计算分数的值。我希望这能让它更清楚。
  • 两个数据框是否具有相同的索引或索引列?考虑先合并您的数据框。

标签: python pandas dataframe levenshtein-distance fuzzy-search


【解决方案1】:

您可以使用包Levenshteinitertools 来获取两列的值组合:

import Levenshtein as lev
from itertools import product

new_df = pd.DataFrame(product(df1['Name'], df2['Name']), columns=["Name1","Name2"])

new_df["LevScore"] = new_df.apply(lambda x: lev.score(x[0],x[1]), axis=1)

print(new_df)

    Name1   Name2   LevScore
0   Name1a  Name1b  1
1   Name1a  Name2b  2
2   Name2a  Name1b  2
3   Name2a  Name2b  1

编辑

假设这是你的 df1:

df1_n = pd.concat([df1,df1,df1]).reset_index(drop=True)
df1_n

Name    Addresss    ID
0   Name1a  Address1a   ID1a
1   Name2a  Address2a   ID2a
2   Name1a  Address1a   ID1a
3   Name2a  Address2a   ID2a
4   Name1a  Address1a   ID1a
5   Name2a  Address2a   ID2a

正如您所说,您可以计算从df1_n 获取大小为step 的值的组合:

fina_df = pd.DataFrame()
step=2
for i in range(0,df1_n.shape[0],step):
    new_df = pd.DataFrame(product(df1_n.iloc[i:i+step,0], df2['Name']), columns=["Name1","Name2"])
    new_df["LevScore"] = new_df.apply(lambda x: lev.distance(x[0],x[1]), axis=1)
    fina_df = pd.concat([fina_df, new_df], axis=0).reset_index(drop=True)

print(final_df)

输出:

Name1   Name2   LevScore
0   Name1a  Name1b  1
1   Name1a  Name2b  2
2   Name2a  Name1b  2
3   Name2a  Name2b  1
4   Name1a  Name1b  1
5   Name1a  Name2b  2
6   Name2a  Name1b  2
7   Name2a  Name2b  1
8   Name1a  Name1b  1
9   Name1a  Name2b  2
10  Name2a  Name1b  2
11  Name2a  Name2b  1

根据您的情况将 2 更改为 300 或 500。这应该避免填满您的整个 RAM,让我知道它是否有效!

【讨论】:

  • 您好,您的解决方案似乎应该适合我,但不幸的是,我运行它的每个人我的整个 PC 都死机了,我需要进行硬重置。原始文件大小约为 8500 行,我已经降低到 3000、1000,现在只有 10 行,但不幸的是在运行代码时遇到了同样的冻结。知道为什么会发生这种情况吗?
  • 所以即使每个数据帧有 10 行,它也不起作用?真的很奇怪!应该生成一个只有 100 行的数据框。
  • 是的,即使只有 10 行,我的整个机器也会卡住。为清楚起见,这是我正在使用的确切代码: new_df = pd.DataFrame(product(df1['CompanyA'], df2['CompanyB']), columns=["CompanyA","CompanyB"]) 也许我是在那里犯了一个我忽略的小错误。或者有没有其他方法可以复制我可以尝试的产品功能?
  • 代码对我来说似乎很好。我不明白为什么机器停止工作。所以问题是当你创建new_df 或之后(在new_df.apply)?
  • 我已经弄清楚为什么它冻结在 10 行,NaN 行没有被正确删除,所以仍然有一堆阻碍,我现在可以处理 10 行。无论如何我可以循环遍历,例如 dfa 中的前 500 个左右与所有 dfb 相比,然后是下一个 500 等?不理想,但可能可行。
【解决方案2】:

试试这个:

import pandas as pd
from textdistance import levenshtein
from itertools import product

# dfa = pd.read_clipboard()  # this is just to reproduce your dataframe

# dfb = pd.read_clipboard()  # this is just to reproduce your dataframe

dfc = pd.DataFrame(product(dfa['Name'], dfb['Name']), columns=['Name1', 'Name2'])

dfc['Distance'] = dfc.apply(lambda x: levenshtein.distance(x['Name1'],
                                                           x['Name2']), axis=1)
    Name1   Name2  Distance
0  Name1a  Name1b         1
1  Name1a  Name2b         2
2  Name2a  Name1b         2
3  Name2a  Name2b         1

【讨论】:

  • 我将删除我的答案,因为我们同时得到了相同的结果:D
  • 体育精神真好,但你可以让 OP 决定我们的命运 :)
  • 您好,您的解决方案似乎应该适合我,但不幸的是,我运行它的每个人我的整个 PC 都死机了,我需要进行硬重置。原始文件大小约为 8500 行,我已经降低到 3000、1000,现在只有 10 行,但不幸的是在运行代码时遇到了同样的冻结。知道为什么会发生这种情况吗?
  • 您正在寻找两列之间所有可能的排列,因此如果它们每列有 8,000 个值,则为 8,000*8,000 个组合:64,000,000 次距离计算。我不知道为什么你会在 10 行时遇到这个问题......
  • 我已经弄清楚为什么它冻结在 10 行,NaN 行没有被正确删除,所以仍然有一堆阻碍,我现在可以处理 10 行。无论如何我可以循环遍历,例如 dfa 中的前 500 个左右与所有 dfb 相比,然后是下一个 500 等?不理想,但可能可行。
猜你喜欢
  • 2020-05-17
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
  • 2013-01-15
相关资源
最近更新 更多