拯救pandas计划(19)——使用自定义方法计算两列的相似度

2023-10-27

拯救pandas计划(19)——使用自定义方法计算两列的相似度

最近发现周围的很多小伙伴们都不太乐意使用pandas,转而投向其他的数据操作库,身为一个数据工作者,基本上是张口pandas,闭口pandas了,故而写下此系列以让更多的小伙伴们爱上pandas。

系列文章说明:

系列名(系列文章序号)——此次系列文章具体解决的需求

平台:

  • windows 10

  • python 3.8

  • pandas >=1.2.4

/ 数据需求

最近在互联网遨游时偶然发现一道很有趣的pandas实例训练题目,题目距今已发布很久,也已经有人为此解答过了,说:有一组数据,每列分别记录着样品的各个指标情况,欲对每个数据各个指标进行计算,求各个样品之间的指标差值的绝对值的总和最小的对应的几个样品,如:a样品:[10.0, 9.0, 7.5, 8.6]b样品:[11.2, 8.7, 6.4, 5.5]之间的相似度计算为:|10.0-11.2|+|9.0-8.7|+|7.5-6.4|+|8.6-5.5|

对应位置相减取绝对值后再相加,为每个样品对其余样品进行计算,求得所有样品的与其相似度最小的5个其他样品。

根据上述描述,构造一组随机数据:

import numpy as np
import pandas as pd

np.random.seed(2022)
data = np.clip(np.random.normal(loc=70, scale=15, size=600).round(2), 0, 100).reshape(60, 10)
df = pd.DataFrame(data, columns=list('abcdefghij'), index=[f'测试_{i}' for i in range(1, 61)])

数据大小为:60*10,浮点型类型。

15193416f29dc4957145c425a2d20e2d.png

/ 需求处理

  • 方法一:笛卡尔积

先计算每个样品的交叉数据,再分组获取组内排名在上的5个数据。

这个方法是该题目下方解答者大佬的方法,其使用的方法进行笛卡尔乘积非常有意思。

df = df.reset_index().rename(columns={'index': '名称'})  
# 设置辅助列
df['one'] = 1
# merge自身,以one列作为key参数合并数据框
df_merge = pd.merge(left=df, right=df, left_on='one', right_on='one')

原数据大小为60*10,乘积后为3600行,内存占用大小相比处理前大了不少,如果数据过大,在处理方面,耗时上会显著增加。

d55d0e1e9717cd7f66d3145ebcd1a612.png

暂且不考虑数据量的影响,继续处理。

# 剔掉名称列和one列
columns = list(df.columns)
columns.remove('名称')
columns.remove('one')


def sim_fun(row):
    sim_value = 0.0
    for col in columns:
        sim_value += abs(round(row[col+'_x'] - row[col+'_y'], 2))
    return round(sim_value, 2)

# 求出每个样品之间的相似值
df_merge['sim'] = df_merge.apply(sim_fun, axis=1)
df_merge = df_merge[df_merge['名称_x'] != df_merge['名称_y']].copy()

# 获取每个样品与其相似值最小的5个样品
def get_top_sims(df_sub):
    df_sort = df_sub.sort_values('sim').head(5)
    names = ','.join(df_sort['名称_y'])
    sims = ','.join(df_sort['sim'].astype(str))
    return pd.Series({'names': names, 'sims': sims})

df_result = df_merge.groupby('名称_x').apply(get_top_sims)

通过复现解答大佬的代码如上,顺利返回了相似度前五的数据框。可以看到在60条数据中使用笛卡尔积进行计算,耗用时间是可以接受的。

3cc49dd2e27d590de1cb1a1c55006179.png
  • 方法二:将每一行数据与原数据直接相减,利用pandas特性求和

在方法一中能注意到数据处理上稍有繁琐,将数据扩容再处理,且数据的差值为逐个计算。仔细理解数据,可以利用数组的广播特性进行处理。

def get_sims(s):
    # 注意:此处的df为全局变量
    df_sim = (df - s).abs().sum(axis=1).round(2)
    df_sim.pop(s.name)
    df_sim = df_sim.sort_values(ascending=False).head(5).astype(str)
    return pd.Series({'names': ','.join(df_sim.index), 'sims': ','.join(df_sim.values)})

# apply按行遍历数据,使其他行与该行进行数据计算
df_result = df.apply(get_sims, axis=1)

使用广播的特性将方法一中的函数优化为get_sims函数,在计算效率上也大大提高。

4ed479c68755c72ddc170da575a7f28a.png

/ 总结

本文通过了解题目目的及其他解答者的想法,根据自身掌握的pandas技巧对题目进行分析处理,在一定程度上减少数据计算的冗余度,满足数据需求,如对本文有不理解之处,尽可发言表述自己的想法。

独乐乐不如众乐乐。


于二零二二年六月二十一日作

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

拯救pandas计划(19)——使用自定义方法计算两列的相似度 的相关文章

  • 用于将 cython 中的许多 C++ 类包装到单个共享对象的项目结构

    我在文档 邮件列表和这个问题在这里 https stackoverflow com questions 10300660 cython and distutils 但我想得到一个更直接的答案来解决我的具体情况 我正在通过尝试一点一点地包装我
  • 无法“安装”plpython3u - postgresql

    我正在尝试在 postgresql 中使用 python 语言 像这样的事情 create or replace function test a integer returns integer as if a 2 0 return even
  • 使用 pythonbrew 编译 Python 3.2 和 2.7 时出现问题

    我正在尝试使用构建多个版本的 python蟒蛇酿造 http pypi python org pypi pythonbrew 0 7 3 但我遇到了一些测试失败 这是在运行的虚拟机上 Ubuntu 8 04 32 位 当我使用时会发生这种情
  • 使用 psycopg2 在 python 中执行查询时出现“编程错误:语法错误位于或附近”

    我正在运行 Python v 2 7 和 psycopg2 v 2 5 我有一个 postgresql 数据库函数 它将 SQL 查询作为文本字段返回 我使用以下代码来调用该函数并从文本字段中提取查询 cur2 execute SELECT
  • 没有名为 crypto.cipher 的模块

    我现在正在尝试加密一段时间 我最近得到了这个基于 python 的密码器 名为PythonCrypter https github com jbertman PythonCrypter 我对 Python 相当陌生 当我尝试通过终端打开 C
  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • 如何在flask中使用g.user全局

    据我了解 Flask 中的 g 变量 它应该为我提供一个全局位置来存储数据 例如登录后保存当前用户 它是否正确 我希望我的导航在登录后在整个网站上显示我的用户名 我的观点包含 from Flask import g among other
  • Django:按钮链接

    我是一名 Django 新手用户 尝试创建一个按钮 单击该按钮会链接到我网站中的另一个页面 我尝试了一些不同的例子 但似乎没有一个对我有用 举个例子 为什么这不起作用
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 基于代理的模拟:性能问题:Python vs NetLogo & Repast

    我正在 Python 3 中复制一小段 Sugarscape 代理模拟模型 我发现我的代码的性能比 NetLogo 慢约 3 倍 这可能是我的代码的问题 还是Python的固有限制 显然 这只是代码的一个片段 但 Python 却花费了三分
  • 绘制方程

    我正在尝试创建一个函数 它将绘制我告诉它的任何公式 import numpy as np import matplotlib pyplot as plt def graph formula x range x np array x rang
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • 在f字符串中转义字符[重复]

    这个问题在这里已经有答案了 我遇到了以下问题f string gt gt gt a hello how to print hello gt gt gt f a a gt gt gt f a File
  • 使用 \r 并打印一些文本后如何清除控制台中的一行?

    对于我当前的项目 有一些代码很慢并且我无法使其更快 为了获得一些关于已完成 必须完成多少的反馈 我创建了一个进度片段 您可以在下面看到 当你看到最后一行时 sys stdout write r100 80 n I use 80覆盖最终剩余的
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • 向 Altair 图表添加背景实心填充

    I like Altair a lot for making graphs in Python As a tribute I wanted to regenerate the Economist graph s in Mistakes we
  • 如何在seaborn displot中使用hist_kws

    我想在同一图中用不同的颜色绘制直方图和 kde 线 我想为直方图设置绿色 为 kde 线设置蓝色 我设法弄清楚使用 line kws 来更改 kde 线条颜色 但 hist kws 不适用于显示 我尝试过使用 histplot 但我无法为
  • 每个 X 具有多个 Y 值的 Python 散点图

    我正在尝试使用 Python 创建一个散点图 其中包含两个 X 类别 cat1 cat2 每个类别都有多个 Y 值 如果每个 X 值的 Y 值的数量相同 我可以使用以下代码使其工作 import numpy as np import mat
  • 使用 Python 绘制 2D 核密度估计

    I would like to plot a 2D kernel density estimation I find the seaborn package very useful here However after searching
  • Rocket UniData/UniVerse:ODBC 无法分配足够的内存

    每当我尝试使用pyodbc连接到 Rocket UniData UniVerse 数据时我不断遇到错误 pyodbc Error 00000 00000 Rocket U2 U2ODBC 0302810 Unable to allocate

随机推荐

  • Python迭代器

    迭代器是在Python2 2中被加入的 它为类序列对象提供了一个类序列的接口 有了迭代器可以迭代一个不是序列的对象 因为它表现出了序列的行为 关于Python中的迭代器 有几个比较容易混淆的概念 可迭代对象 iterable 迭代器 ite
  • 《服务器无状态设计:为什么&如何实现无状态API?》

    博主猫头虎 带您 Go to New World 博客首页 猫头虎的博客 面试题大全专栏 文章图文并茂 生动形象 简单易学 欢迎大家来踩踩 IDEA开发秘籍专栏 学会IDEA常用操作 工作效率翻倍 100天精通Golang 基础入门篇 学会
  • python3 多线程_Python3多线程及线程池实现教程

    一 说明 多线程这个东西 感觉一直以来都是用一次就要学一次 今天需要将之前写的脚本改成线程池的形式又学习了一轮 为了以后方便在这直接记下来 二 多线程实现 2 1 多线程的基本实现 importthreadingimporttimeimpo
  • 编写程序,根据用户输入的两位数,反向显示出该数中的数字。例如,用户输入48,那么程序输出84。(C语言)

    include
  • Linux开机满进度条卡死问题

    Linux开机满进度条卡死问题 此问题意外发生 原本好好的 再次开机就发现启动时进度条很慢 最后满条卡住 但ssh方式连接还能进去 也就是开机了 但linux界面卡住了 页面如下 但我们使用xshell进行ssh链接还是可以用的 但进度条卡
  • Ubuntu---pycharm卸载

    Ubuntu卸载pycharm 1 在 Linux 上卸载 snap 包 在商店中直接下载 专业版 sudo snap remove pycharm professional 社区版 sudo snap remove pycharm com
  • tomcat能作为网站的服务器不,tomcat的作用是什么_网站服务器运行维护,tomcat

    Linux 如何查看root密码 网站服务器运行维护 Linux不能查看root密码 因为root密码都是密文存储的 而密码设计的一个目标就是反推解密出来的可能性尽量小 如果需要修改密码 可以通过进入单用户模式下 将密码进行修改 修改完成后
  • SlideLive:提供小清新风格PPT模板下载

    简介 在学习和工作中 有时需要制作PPT 本文主要介绍如何从SlideLive平台下载小清新风格PPT模板 其中 SlideLive是一款PPT在线播放和分享的网站 该网站已收录大量的PPT模板 包括各种风格PPT模板和PPT图表 下载地址
  • 4款不错的UI设计软件推荐

    俗话说 如果工人想做好工作 他们必须首先磨利他们的工具 高质量的UI设计软件将使设计事半功倍 近年来 UI设计软件的逐渐多样化 让一些需要使用UI设计软件的小伙伴不知道如何选择 我整理了四款优秀的免费UI设计软件 别错过了 1 即时设计 即
  • 在子组件中使用Echarts图表无法刷新显示的问题(解决:子组件刷新)

    场景问题 在项目中 子组件中使用了Echarts的图表 图表的数据需要从父组件传入Id来进行查询 墒情仪与气象站相同的结构 当切换设备时 图表无法回显 父子组件传值正常 解决心路历程 1 我将两种设备传值的Id分开传递 处理无果 2 给子组
  • Linux下操作Docker(四):导入导出

    docker镜像的导出和导入 显示当前docker中的镜像 docker images 镜像列表如下 REPOSITORY TAG IMAGE ID CREATED SIZE pointsift latest 90b2ef439b40 2
  • java循环判断的使用

    程序的结构 一般来说程序的结构包含有下面三种 1 顺序结构 2 选择结构 3 循环结构 顺序结构 程序至上而下逐行执行 一条语句执行完之后继续执行下一条语句一直到程序的末尾 选择结构 是根据条件的成立与否 再决定要执行哪些语句的一种结构 循
  • 原生js实现简单智能关键词搜索功能

    现在很多网站都有智能搜索功能 它能根据用户的输入自动提示出需要补全的数据 方便用户的查询 下面我们用JavaScript来简单实现它 html部分 div div
  • STM32学习笔记3:KEIL5中使用ST-Link烧录调试STM32芯片的步骤

    一 开发板连接ST LINK ST LINK连接电脑 操作细节点击这里 二 配置debug选项 点击魔术棒 debug use 项选择 ST Link Debugger 再点击 Setting 这边会显示设备信息 如果显示没有设备 需要检查
  • 数字电路设计之OpenRISC(一)

    ARM PowerPC等商用IP核授权费价格较高 所以开源处理器越来越受到大家的关注 开源处理器比如OpenRISC NIOS II LEON2等 这里我会介绍OpenRISC的优点 一 指令集可扩展 二 添加专用的硬件协处理单元 一般来说
  • Kettle(一) 下载及环境部署

    1 kettle下载地址 kettle资源 https download csdn net download kingo0 87360222 JDK资源 LinuxJDK1 8安装包 jdk1 8安装包 Java文档类资源 CSDN下载 2
  • oracle 触发器 for each row 理解

    看到了触发器 中有个 for each row 不是很明白就查了查资料 因为只是简单研究 就先写总结一下 触发器的一般语法 CREATE OR REPLACE TIGGER 触发器名 触发时间 触发事件 ON 表名 FOR EACH ROW
  • AndroidStudio中Module创建及项目变Module导入其它项目步骤

    AndroidStudio中Module创建及项目变Module导入其它项目步骤记录 1 创建module 2 添加依赖 3 将已有项目变为module导入到其他项目中 将已有项目更改 将旧项目作为module导入 4 遇到的一些问题 总结
  • Ceres Solver安装及bug解决

    Ceres Solver安装与入门使用 安装教程 http www ceres solver org installation html 点击下载最新的稳定版 解压 编译 测试 安装 1 Linux系统下安装步骤 安装依赖 CMake su
  • 拯救pandas计划(19)——使用自定义方法计算两列的相似度

    拯救pandas计划 19 使用自定义方法计算两列的相似度 最近发现周围的很多小伙伴们都不太乐意使用pandas 转而投向其他的数据操作库 身为一个数据工作者 基本上是张口pandas 闭口pandas了 故而写下此系列以让更多的小伙伴们爱