摘要

本文介绍了使用 Pandas 进行数据挖掘时常用的加速技巧。

实验环境

import numpy as np
import pandas as pd
print(np.__version__)
print(pd.__version__)
1.16.5
0.25.2

性能分析工具

本文使用到的性能分析工具,参考:Python 性能评估 学习笔记

数据准备

tsdf = pd.DataFrame(np.random.randint(1, 1000, (1000, 3)), columns=['A', 'B', 'C'],index=pd.date_range('1/1/1900', periods=1000))
tsdf['D'] = np.random.randint(1, 3, (1000, ))
tsdf.head(3)
         A   B   C
1900-01-01  820 827 884 1
1900-01-02  943 196 513 1
1900-01-03  693 194 6   2

使用 numpy 数组加速运算

map, applymap, apply 之间的区别,参考:Difference between map, applymap and apply methods in Pandas

apply(func, raw=True)

Finally, apply() takes an argument raw which is False by default, which converts each row or column into a Series before applying the function. When set to True, the passed function will instead receive an ndarray object, which has positive performance implications if you do not need the indexing functionality.
Pandas 官方文档

DataFrame.apply() 支持参数 raw,为 True 时,直接将 ndarray 输入函数,利用 numpy 并行化加速。
有多快?

%%timeit
tsdf.apply(np.mean)  # raw=False (default)
740 µs ± 28.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
tsdf.apply(np.mean, raw=True)
115 µs ± 2.76 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

由 740 微秒降低到 115 微秒。
什么条件下可以使用?

  1. 只有 DataFrame.apply() 支持,Series.apply() 和 Series.map() 均不支持;
  2. func 不使用 Series 索引时。
tsdf.apply(np.argmax)  # raw=False, 保留索引
A   2019-12-08
B   2021-03-14
C   2020-04-09
D   2019-11-30
dtype: datetime64[ns]
tsdf.apply(np.argmax, raw=True)  # 索引丢失
A      8
B    470
C    131
D      0
dtype: int64

.values

多个 Series 计算时,可以使用 .values 将 Series 转换为 ndarray 再计算。

%%timeit
tsdf.A * tsdf.B
123 µs ± 2.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
tsdf.A.values * tsdf.B.values
11.1 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

由 123 微秒降低到 11 微秒。
补充说明
注意到 Pandas 0.24.0 引入了 .array 和 .to_numpy(),参考。但这两种方法的速度不如 values,建议在数据为数值的情况下继续使用 values。

%%timeit
tsdf.A.array * tsdf.B.array
37.9 µs ± 938 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
tsdf.A.to_numpy() * tsdf.B.to_numpy()
15.6 µs ± 110 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

可见两种方法均慢于 values 的 11 微秒。

字符串操作优化

数据准备

tsdf['S'] = tsdf.D.map({1: '123_abc', 2: 'abc_123'})
%%timeit
tsdf.S.str.split('_', expand=True)[0]  # 得到'_'之前的字符串
1.44 ms ± 97.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

一种优化思路是:针对特定场景,不需要使用 split,可以改用 partition:

%%timeit
tsdf.S.str.partition('_', expand=True)[0]
1.39 ms ± 44.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

速度略有提升。试试 apply :

%%timeit
tsdf.S.apply(lambda a: a.partition('_')[0])
372 µs ± 8.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

可见使用 apply 速度反而比 Pandas 自带的字符串处理方法要快,这可能是因为 Pandas 支持的数据类型多,处理过程中存在一些冗余的判断。
注意到原有数据只有2种,理论上对每一种数据取值只需要计算一次,其它值直接 map 就行。因此考虑转换为 Categorical 类型:

tsdf['S_category'] = tsdf.S.astype('category')
%%timeit
tsdf.S_category.apply(lambda a: a.partition('_')[0])
246 µs ± 3.36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

耗时降低至 246 微秒。

IO 优化

Pandas 性能优化 学习笔记相关推荐

  1. mysql性能优化-学习笔记

    mysql性能优化-学习笔记

  2. kvm虚拟化学习笔记(二十一)之KVM性能优化学习笔记

    本学习笔记系列都是采用CentOS6.x操作系统,KVM虚拟机的管理也是采用virsh方式,网上的很多的文章都基于ubuntu高版本内核下,KVM的一些新的特性支持更好,本文只是记录了CentOS6. ...

  3. js性能优化--学习笔记

    <高性能网站建设进阶指南>: 1.使用局部变量,避免深入作用域查找,局部变量是读写速度最快的:把函数中使用次数超过一次的对象属性和数组存储为局部变量是一个好方法:比如for循环中的.len ...

  4. mysql性能优化学习笔记

    mysql性能优化 硬件对数据库的影响 CPU资源和可用内存大小 服务器硬件对mysql性能的影响 我们的应用是CPU密集型? 我们的应用的并发量如何? 数量比频率更好 64位使用32位的服务器版本 ...

  5. 数据库mysql性能优化-学习笔记

    数据库mysql性能优化 1. 数据库设计范式 2. 常见关系数据库 3. MySQL 的版本 4. mysql存储计划 5 . mysql查询配置 和 设置配置 6 . mysql基本参数 7 .m ...

  6. 熟悉mysql数据库设计和性能优化_MySQL性能优化学习笔记-(1)数据库设计

    一.数据库设计 1.数据类型优缺点分析 数据类型的选择要遵循的总体原则 更小的通常更好 一般情况下,应该尽量选择使用可以正确存储数据的最小数据类型.更小的数据类型通常更快,因为它们站用更小的磁盘.内存 ...

  7. mysql性能优化学习笔记-存储引擎

    mysql体系架构 客户端(java.php.python等) mysql服务层(连接管理器.查询解析器.查询优化器.查询缓存) mysql存储引擎(innodb.myisam等) 存储引擎针对表而言 ...

  8. mysql性能优化 硬件优化_mysql性能优化学习笔记(6)数据库配置优化硬件优化...

    一.操作系统配置优化: 1. 网络方面,修改/etc/sysctl.conf文件,增加tcp支持的队列数,减少断开连接时,资源的回收. 2. 打开文件数的限制.修改/etc/security/limi ...

  9. 嵌入式算法移植优化学习笔记5——CPU,GPU,TPU,NPU都是什么

    嵌入式算法移植优化学习笔记5--CPU,GPU,TPU,NPU都是什么 一.什么是CPU? 二.什么是GPU? 三.什么是NPU? 四.什么是TPU? 附: 随着AI的广泛应用,深度学习已成为当前AI ...

最新文章

  1. SpreadJS 在 Angular2 中支持绑定哪些属性?
  2. sqlldr,将数据批量导入Oracle数据库
  3. Python 之 风格规范(Google )
  4. Lazarus安装使用
  5. GIS实战应用案例100篇(七)-基于GIS和ENVI的矢量化提取水体边界
  6. C 的Pair用法分类整理(精)
  7. Visual Studio引入外部库 ---- 弄懂静态库lib和动态库dll
  8. 累计增量备份策略_数据安全与备份解决方案ZDLRA快速恢复
  9. 读书笔记 effective c++ Item 34 区分接口继承和实现继承
  10. 实操教程:Android部署Nanodet模型完成实时高效的物体检测
  11. 2020年西南交通大学数据仓库与数据挖掘期末考试题
  12. vim内部实现完美运行代码和脚本
  13. 两个分数化简比怎么化_分数化简比的方法什么,六年级上求比值与化简比的对比...
  14. Young不等式的一个新证明
  15. 高一计算机课期中考试总结反思,期中考试总结与反思(精选25篇)
  16. [转载] 晓说——第17期:揭秘战争秘闻 朝鲜战争62年祭(下)
  17. apple tv设置_如何设置Apple TV以自动打开电视或媒体中心
  18. 微信朋友圈视频变长从6秒增加为10秒
  19. BZOJ4372: 烁烁的游戏(动态点分治)
  20. 如何在服务器上编辑配置文件

热门文章

  1. Dayt07-自增和自减
  2. SpringBoot——基础开发(上)
  3. rsync客户端同步报错
  4. 基于AntBlazor的学生在线练习系统实现过程的简单总结
  5. 微信公众号如何获取手机号,H5调用小程序,小程序调用H5
  6. cheat engine
  7. 涂鸦云平台设备授权介绍
  8. linux下quota实现用户的硬盘配额
  9. bat拷贝与powershell拷贝
  10. Linux下安装SVN服务端教程