在进行文本相似度评分时如何矢量化和加速 pandas 数据帧的双 for 循环

2024-01-10

我有以下数据框:

d_test = {
    'name' : ['South Beach', 'Dog', 'Bird', 'Ant', 'Big Dog', 'Beach', 'Dear', 'Cat'],
    'cluster_number' : [1, 2, 3, 3, 2, 1, 4, 2]
}
df_test = pd.DataFrame(d_test)

我想识别相似的名字name列(如果这些名称属于一个簇号)并为它们创建唯一的 ID。例如South Beach and Beach属于簇号1而且他们的相似度得分相当高。所以我们将它与唯一的 id 关联起来,比如说1。下一个簇是数字2和三个实体来自name属于该簇的列:Dog, Big Dog and Cat. Dog and Big Dog具有很高的相似度分数,并且他们的唯一 ID 是,比如说2. For Cat唯一的ID将是,比如说3。等等。

我为上面的逻辑创建了一个代码:

# pip install thefuzz
from thefuzz import fuzz

d_test = {
    'name' : ['South Beach', 'Dog', 'Bird', 'Ant', 'Big Dog', 'Beach', 'Dear', 'Cat'],
    'cluster_number' : [1, 2, 3, 3, 2, 1, 4, 2]
}

df_test = pd.DataFrame(d_test)

df_test['id'] = 0

i = 1
for index, row in df_test.iterrows():
    for index_, row_ in df_test.iterrows():
        if row['cluster_number'] == row_['cluster_number'] and row_['id'] == 0:
            if fuzz.ratio(row['name'], row_['name']) > 50:
                df_test.loc[index_,'id'] = int(i)
                is_i_used = True
    if is_i_used == True:
        i += 1
        is_i_used = False
                           

代码生成预期结果:

    name        cluster_number id
0   South Beach 1              1
1   Dog         2              2
2   Bird        3              3
3   Ant         3              4
4   Big Dog     2              2
5   Beach       1              1
6   Dear        4              5
7   Cat         2              6

注意,对于Cat we got id as 6但这很好,因为无论如何它都是独一无二的。

虽然上面的算法适用于测试数据,但我无法将其用于我拥有的真实数据(大约 100 万行),并且我试图了解如何矢量化代码并摆脱两个 for 循环。

Also thefuzz模块有process函数,它允许立即处理数据:

from thefuzz import process
out = process.extract("Beach", df_test['name'], limit=len(df_test))

但我不知道它是否有助于加快代码速度。


tl;dr:如果 N 很大,请避免 O(N^2) 运行时间。

帮助加快代码速度。

人们沮丧.iterrows(),称之为“慢”。

切换自.iterrows向量化方法 可能会在某种程度上“加快速度”,但这是一个相对的衡量标准。 我们来谈谈复杂性。

时间复杂度

您当前的算法是二次的; 它具有一对嵌套的.iterrows循环。 但我们立即过滤

        if different_cluster and not_yet_assigned:

现在,这对于“小”N 来说可能是可行的。 但 400K 的 N 很快就变得不可行:

>>> 419_776 ** 2 / 1e9
176.211890176

一千七百六十亿次迭代(带“B”) 没什么可打喷嚏的, 即使每个过滤步骤的成本微不足道(但非零)。

冒着背诵已经乏味的事实的风险 之前重复过很多次,

  • 排序成本 O(N log N),以及
  • N log N 远小于 N^2

我不相信你想要的是“走快”。 相反,我怀疑你真正想要的是“少做一些”。 首先对行进行排序,然后进行 大致线性的传递that数据集。

您没有指定典型的集群组大小 G。 但由于有许多不同的簇号, 我们肯定知道 G


df = df_test.sort_values(['cluster_number', 'name'])

你写了

for index, row in df_test.iterrows():
    for index_, row_ in df_test.iterrows():

把它变成

for index, row in df.iterrows():
    while ...

and use .iloc()检查相关行。

The while循环尽快终止 当看到新的簇号时, 每次都必须费力地通过数十万 行直到看到数据帧末尾。

为什么能够提前退出? 由于排序顺序。


构建此结构的更方便的方法可能是 编写一个聚类助手。

def get_clusters(df):
    cur_num = -1
    cluster = []
    for _, row in df.iterrows():
        if row.cluster_number != cur_num and cluster:
            yield cluster
            cluster = []
        cur_num = row.cluster_number
        cluster.append(row)

现在你的顶级代码可以迭代一堆 簇,执行成本 O(G^2) 的模糊匹配 在每个集群上。

每个生成的簇的不变量 是簇内的所有行 应具有相同的 cluster_number。

并且,由于排序, 我们保证给定的 cluster_number 最多生成一次。


https://stackoverflow.com/help/self-answer https://stackoverflow.com/help/self-answer

请测量当前运行时间, 实施这些建议, 再次测量, 以及邮政编码+时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在进行文本相似度评分时如何矢量化和加速 pandas 数据帧的双 for 循环 的相关文章

随机推荐

  • 如何在返回集合的 lambda 中使用异步

    我有一个异步 上游 方法 我试图遵循最佳实践 并在堆栈中全力以赴地进行异步 在 MVC 内的控制器操作中 如果我依赖 Result 我可以预料到会遇到死锁问题 将控制器操作更改为异步似乎是可行的方法 但问题是异步方法在 lambda 中被多
  • SSMS 从我的存储过程中删除预 BEGIN 注释

    我正在运行 SSMS 12 0 2000 8 如果我使用SSMS查询编辑器创建一个存储过程 如下例 之前的注释BEGIN当我执行 保存它时被删除 CREATE PROCEDURE myproc Say goodbye to this com
  • C# 检查 JSON 文件是否包含字符串

    我正在尝试这样做 以便我可以检查字符串是否在 json 中 例如 在我的 JSON 文件中存在 name Disp R name Disp L name Disp C 每当 Disp 在字符串中时 整个值都应该存储在列表中 我就是这样做的
  • MySql:限制一张表中某一列的更新权限

    我有一个表 我们称之为学生表 其模式称为注册 表学生有一个名为地址的列 我不希望某个用户更新该列 其他权限都可以 例如选择 插入 该表中以及该架构中的所有其他列都应该具有更新权限 这可行吗 您可以设置数据库 表 列的权限 但我真的不会尝试在
  • 艾里函数积分的根(matlab)

    我想解下面的方程 我在函数的定义上做错了 但我仍然不明白 function F myairyint x F integral x airy x 1000 end functi2 x myairyint x0 1 1 15 fsolve fu
  • 如何以可微分的方式计算几何平均值?

    如何使用 Pytorch 计算沿某个维度的几何平均值 有些数字可能是负数 该函数必须是可微的 几何平均值的已知 合理 数值稳定版本是 import torch def gmean input x dim log x torch log in
  • 有没有办法将通用列表转换为接口/基类类型列表?

    我试图向某人展示接口在他们创建的疯狂情况下的用途 它们在列表中有几个不相关的对象 并且需要对每个对象中的两个字符串属性执行操作 我指出 如果他们将属性定义为接口的一部分 他们可以使用接口对象作为作用于它的方法参数的类型 例如 void Pr
  • AES 加密和密钥存储?

    几年前 当我第一次接触 ASP net 和 NET Framework 时 我构建了一个非常简单的在线文件存储系统 该系统使用 Rijndael 加密来存储服务器硬盘上的加密文件 并使用 HttpHandler 来解密并将这些文件发送到客户
  • 手动编辑 Excel 365 并使用图形 API 延迟读取

    我有一个 Excel 在线文档 用户可以在 Excel 365 Web 应用程序中编辑该文档 我有一个使用图形 API 读取此 Excel 文件的应用程序 我已经成功地从文件中读取数据 但是当用户更改 Excel 文件并且 Excel 表示
  • 是否可以在 Rx 中的不同线程上调用订阅者的 OnNext?

    我是 Rx 新手 我想知道是否可以将消息分派给不同的订阅者 以便它们在不同的线程上运行 IObserable 如何控制它 据我了解 简单的主题实现是在单个线程上一个接一个地调用订阅者 public class Subsciber IObse
  • PostgreSQL整数数组值使用desc字符串连接到其他表中的整数

    我有一张桌子test包含 int 数组和值的列 例如 1000 4000 6000 or 1000 or 1000 4000 called ekw 这些值与另一个表中的描述字符串匹配 tab test id name ekw 1 One 1
  • 索引 Pandas 数据帧时出现 KeyError

    我正在尝试将 csv 文件中的数据读取到 pandas 数据框中 并访问第一列 日期 import pandas as pd df ticks pd read csv values csv delimiter print df ticks
  • git show HEAD^ 似乎不起作用。这是正常的吗?

    我正在使用 Zsh 并尝试为项目运行 git show 以查看我的修订历史记录 如果我做 git show HEAD 它可以很好地向我显示我的最后一次提交 但是以下命令不起作用 master 5 project git show HEAD
  • 如何在 Google Datastore 中添加复合索引?

    我现在使用 Google Datastore 作为我公司的数据库 今天 我做了一个索引 它成功地列在 索引 中 但是我创建的索引的大小和实体是空的 谷歌数据存储的文档说索引是自动生成的 但事实并非如此 是否有任何命令或执行某些操作来生成索引
  • 简单的社区网站是否需要 SSL 证书?

    我正在努力部署一个小型社区网站 用户注册只需要用户名 电子邮件地址和密码 我什至不要求提供姓名 当然也不会存储任何敏感数据 我还应该投资 SSL 证书吗 在没有密码的情况下传输用户密码会被认为是一种糟糕的做法吗 这只是一个个人项目 所以我想
  • 适用于 Android 的 REST API 客户端库

    我们正在构建一个基于位置的消息应用程序 它使用 Parse com 作为后端 Parse com 类似于 Urban Airship PubNub 等 我们现在想要切换到我们自己的后端以获得更好的控制 为此 我们构建了一个基于 Node j
  • 如何使用 Firestore 查询的结果填充微调器?

    我正在创建一个spinner这将显示主题名称 主题名称存储在我的 Firestore 数据库中 如下所示 subjects collection SUB01 document name Android SUB02 name Java 我可以
  • 在注释功能中设置箭头和文本之间的垫

    如何在 matplotlib 的注释函数中设置箭头和文本之间的距离 填充 有时 文本最终距离箭头太近 我想将它们移得更远一些 基本示例 import matplotlib pyplot as plt plt annotate Here it
  • RavenDB Id 和 ASP.NET MVC3 路由

    只是使用 MVC 3 RC2 和 RavenDB 构建一个快速 简单的站点来测试一些东西 我已经能够制作一堆项目 但我很好奇 Html ActionLink 如何处理 raven DB ID 我的例子 我有一个名为 reasons 的文档
  • 在进行文本相似度评分时如何矢量化和加速 pandas 数据帧的双 for 循环

    我有以下数据框 d test name South Beach Dog Bird Ant Big Dog Beach Dear Cat cluster number 1 2 3 3 2 1 4 2 df test pd DataFrame