首页 > 其他分享 >Pandas:如何让你的代码性能飙升

Pandas:如何让你的代码性能飙升

时间:2024-03-18 18:26:47浏览次数:22  
标签:df 代码 飙升 pandas 000 数据 Pandas 评估 row

在数据分析相关的工作中,Pandas无疑是一个强大的工具,它的易用性和灵活性广受青睐。
然而,随着数据量的不断增长和计算需求的日益复杂,Pandas代码的性能问题也逐渐浮出水面。
如何让Pandas代码运行得更快、更高效,成为了每一个人使用者都需要面对的挑战。

今天,本文就一个简化版的实际分析案例,来一起探讨Pandas代码如何写才能性能更好,让你的数据处理流程更加顺滑,不再为漫长的等待运行而烦恼。

1. 案例介绍

假设有个股票分析的场景,我们需要给所有的股票每天的交易情况做一个评估,评估的结果有3个级别:
其中,“优”的条件是当天成交额大于10亿收盘价大于开盘价,也就是股票上涨;
“差”的条件是当天成交额小于1亿收盘价小于开盘价,也就是股票下跌;
除此之外的情况就是“中”

再次强调一下,这是一个简化的评估方法,主要是为了下面演示Pandas的代码性能,真实的评估不会如此粗糙。

股票交易的数据来自A股2024年1,2月份的日交易数据,大约20多万条。
数据可从地址 https://databook.top/stock/2024 下载。

导入数据:

import pandas as pd

# 这个路径根据实际情况修改
fp = r'D:\data\2024\历史行情数据-东财-不复权-2024.csv'

df = pd.read_csv(fp)
df = df.loc[:, ["股票代码", "日期", "开盘", "收盘", "最高", "最低", "成交量"]]
df

image.png

2. 不同写法的性能比较

下面是3种代码的写法都是基于pandas的,完成的功能也是一样的。

2.1. 循环遍历

给每条数据加一个评估的指标,最直接想到的方法就是遍历所有的数据,然后根据每条数据的情况,
给予一个评估指标(优,中,差)。

首先,封装一个评估一条数据的函数:

def eval_stock(row):
    """
    评估一条的数据
    """
    # 成交额
    volumn = row["收盘"] * row["成交量"]
    
    if volumn > 1_000_000_000 and row["收盘"] > row["开盘"]:
        return "优"

    if volumn < 100_000_000 and row["收盘"] < row["开盘"]:
        return "差"

    return "中"

然后用遍历的方式评估我们准备的数据(A股2024年1,2月份的日交易数据)。

for idx, row in df.iterrows():
    df.loc[idx, "评估"] = eval_stock(row)

df

image.png

虽然只有20多万条数据,但是执行时间还挺长的,在jupyter notebook 中用 %%timeit 魔法函数测试性能如下。

%%timeit
for idx, row in df.iterrows():
    df.loc[idx, "评估"] = eval_stock(row)

运行结果:

36.4 s ± 367 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

执行一次要36秒多,效率很低。

2.2. apply方法

apply方法是pandas提供的一种灵活处理数据的接口,它允许我们传入一个自定义函数来处理数据。
下面我们看看这种方式的性能如何。

%%timeit
df["评估"] = df.apply(eval_stock, axis=1)

运行结果:

4.9 s ± 86.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

性能提升非常明显(36.4秒->4.9秒),代码也变得更加简洁。

2.3. 向量化方法

最后,我们看看终极的写法,这种写法把pandas的数据结构DataFrame看成是一个一维的向量数组(每列一个向量),而不是一个二维的数值数组。
这样,我们操作数据是以为单位来操作,看看这样写的性能如何:

%%timeit
df["评估"] = "中"
df.loc[
    (df["收盘"] * df["成交量"] > 1_000_000_000) & (df["收盘"] > df["开盘"]),
    "评估",
] = "优"
df.loc[
    (df["收盘"] * df["成交量"] < 100_000_000) & (df["收盘"] < df["开盘"]), "评估"
] = "差"

运行结果:

8.22 ms ± 434 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

运行时间几乎可以忽略不计

3. 总结

同样使用pandas写数据分析的代码,性能差距居然会如此天差地别。

可见,学习pandas,不仅仅是学习它的各种接口和函数,
更重要的是了解从pandas执行的角度应该如何看待数据,是把数据看成一个一个独立的值,还是一行一行或一列一列的向量。
只有这样,才能用pandas高效的处理数据,这在数据量膨胀之后,会大大提高我们分析的效率。

标签:df,代码,飙升,pandas,000,数据,Pandas,评估,row
From: https://www.cnblogs.com/wang_yb/p/18081105

相关文章

  • Nodgd 亲笔代码!!!
    AVL:#include<bits/stdc++.h>usingnamespacestd;structNode{intkey;intson[2],hei;}node[12345678];inttotal;structAVL{introot;voidupdate(inti){node[i].hei=max(node[node[i].son[0]].hei,node[node[i].s......
  • 揭秘极致编程体验:代码背后的魔法世界
    想象一下,你手中有一把魔法棒,只需轻轻一挥,就能让计算机为你实现各种神奇的功能。其实,这把魔法棒就是编程语言,而你就是那位魔法师。今天,我们就来一起探索这个代码背后的魔法世界,看看如何创造一次极致的编程体验。编程:从0到1的创造之旅编程,简单来说,就是告诉计算机如何执行任务......
  • Java 代码执行本地命令
    byemanjusakafromhttps://www.emanjusaka.top/2024/03/java-exec-local-command彼岸花开可奈何本文欢迎分享与聚合,全文转载请留下原文地址。我们可以在命令行中执行各种命令,比如,创建文件、查看文件夹下文件、调用第三方工具等等。如果想在java代码中执行命令应该怎么......
  • jenkins与gradle与sonar集成自动化打包代码检测
    来源:https://juejin.cn/post/6844903536061317133服务器以ubuntu操作系统,服务器上已经安装jenkins,sonar服务,并且正常启动访问。本人主要介绍gitlab,fir与sonar如何与jenkins进行集成安装gradle插件并且配置ANROID_HOME,jdk,gradle路径Jenkins->系统管理->可选插件->......
  • 代码随想录算法训练营第23天|669. 修剪二叉搜索树|108.将有序数组转换为二叉搜索树|53
    代码随想录算法训练营第23天|669.修剪二叉搜索树|108.将有序数组转换为二叉搜索树|538.把二叉搜索树转换为累加树|总结篇669.修剪二叉搜索树这道题目比较难,比添加增加和删除节点难的多,建议先看视频理解。题目链接/文章讲解:https://programmercarl.com/0669.%E4%BF%A......
  • 代码随想录算法训练营第27天|39. 组合总和|40.组合总和II|131.分割回文串
    代码随想录算法训练营第27天|39.组合总和|40.组合总和II|131.分割回文串详细布置39.组合总和本题是集合里元素可以用无数次,那么和组合问题的差别其实仅在于startIndex上的控制题目链接/文章讲解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%9......
  • 基于51单片机的波形发生器(5种,调频)原理图、流程图、物料清单、仿真图、源代码
    基于51单片机的波形发生器(5种,调频)设计一个单片机控制的信号发生器。用处理器系统的控制可用于生成各种波形,例如方波,三角波,锯齿波,正弦波等。可以调整信号发生器产生的波形的频率。信号波形可以通过软件更改。基本要求:(1)产生三种以上波形。如正弦波、三角波、矩形波等。......
  • 基于51单片机的波形发生器(4种,振幅,频率,相差)原理图、流程图、物料清单、仿真图、源代码
    基于51单片机的波形发生器(4种,振幅,频率,相差)双通道信号发生器1、可通过串口设置波形灯参数2、输出正弦波、方波、三角波或锯齿波3、波的类型、振幅、频率可调4、波的相位差可调#include<reg51.h>#include"absacc.h"#include"intrins.h"#include"lcd1602.h"......
  • leetcode代码记录(二分查找
    目录1.题目:2.我的代码:小结:1.题目:给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在nums中并且......
  • dea设置自动编译spring boot代码,idea代码修改后无须重启服务立即生效
    解决办法1:spring-boot-devtools<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><......