首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Pandas内存优化和数据加速读取

Pandas内存优化和数据加速读取

作者头像
double
发布2019-12-23 16:57:19
2.5K0
发布2019-12-23 16:57:19
举报
文章被收录于专栏:算法channel算法channel

以下文章来源于AI蜗牛车,作者贝壳er

Pandas 是常用的 Python 软件库,可用于数据操作和分析。在进行数据分析时,导入数据(例如pd.read_csv)几乎是必需的,但对于大的CSV,可能会需要占用大量的内存和读取时间,这对于数据分析时如果需要Reloading原始数据的话会非常低效。Dataquest.io 发布了一篇关于如何优化 pandas 内存占用的教程,仅需进行简单的数据类型转换,就能够将一个棒球比赛数据集的内存占用减少了近 90%,而pandas本身集成上的一些压缩数据类型可以帮助我们快速读取数据。 作者知乎:https://www.zhihu.com/people/bei-ke-er-1-34/activities

1. 内存优化

一个现象是,在使用pandas进行数据处理的时候,加载大的数据或占用很大的内存和时间,甚至有时候发现文件在本地明明不大,但是用pandas以DataFrame形式加载内存中的时候会占用非常高的内存。

这里首先考虑python中的子类型(subtype)。pandas 内部将数值表示为 NumPy ndarrays,因为 pandas 表示同一类型的每个值时都使用同样的字节数,而 NumPy ndarray 可以存储值的数量,所以 pandas 可以快速准确地返回一个数值列所消耗的字节数。下表给出的各子类型所占的字节数。

关于数据存储,有这样一个比方,内存相当于仓库,数字相当于货物,数字需要装到箱子里才能堆到仓库。现在有小,中,大三种箱子,我们一个个数字用小箱子就可以装好,然后堆到仓库去,而现在pandas的处理逻辑是,如果你不告诉用哪个箱子,我都会用最大的箱子去装,这样仓库很快就满了。OK,这就是有时候DataFrame内存占用过高的原因。

所以这里有个简单的思路是:我依次去遍历数据的所有列,检查每一列的数值范围包含在哪个最近的子类区间。我们可以用np.iinfo()来获取子类的范围,例如:np.iinfo(np.int8).min为-128, np.iinfo(np.int8).max为127,也就是在数据不溢出的前提下,in8的数值范围是-128~127,由前面可以知道,如果一个数为int型,pandas读进来后就是int64的类型,也就是占8 bytes,如果这列数最大为100,最小为1,那么用int64去存储他显然浪费了内存,所以我们可以astype他的类型为in8,这样相当于对内存进行了一个压缩优化,可以减小不少的内存,同等硬件条件下,处理数据变得更高效。

同样对float类型数据也做相同的处理。对于object型,下图对比展示了数值型数据怎样以Numpy数据类型存储,和字符串怎样以Python内置类型进行存储的:

和数值类数据不同, object 类型的内存使用是可变的。尽管每个指针仅占用 1 字节的内存,但如果每个字符串在 Python 中都是单独存储的,那就会占用实际字符串那么大的空间。

解决的办法是:pandas 在 0.15 版引入了 Categorials。category 类型在底层使用了int值来表示一个列中的值,而不是使用原始值。pandas 使用一个单独的映射词典将这些int值映射到原始值。只要当一个列包含有限的值的集合时,这种方法就很有用。当我们将一列转换成 category dtype 时,pandas 就使用最节省空间的 int 子类型来表示该列中的所有不同值。所以我们可以将object型数据astype成category 类型以优化存储空间。

2. 采用压缩格式存储

通常,在构建复杂数据模型时,可以方便地对数据进行一些预处理。例如,如果您有10年的分钟频率耗电量数据,即使你指定格式参数,只需将日期和时间转换为日期时间可能需要20分钟。你真的只想做一次,而不是每次运行你的模型,进行测试或分析。你可以在此处执行的一项非常有用的操作是预处理,然后将数据存储在已处理的表单中,以便在需要时使用。但是,如何以正确的格式存储数据而无需再次重新处理?如果你要另存为CSV,则只会丢失datetimes对象,并且在再次访问时必须重新处理它。

Pandas本身有内置的解决方案,例如 HDF5和feather format , HDF5是一种专门用于存储表格数据阵列的高性能存储格式。Pandas的 HDFStore 类允许你将DataFrame存储在HDF5文件中,以便可以有效地访问它,同时仍保留列类型和其他元数据。它是一个类似字典的类,因此您可以像读取Python dict对象一样进行读写。而feather format也是内置的一个压缩格式,在读取的时候会获得更快的加速。

3. 优化效果展示

这里我将这种优化方法写成一个类,并分别提供数据的压缩优化以及读取加速的API,以方便去使用他:GitHub[1]

可以看出,原CSV文件占用内存为616.95MB,优化内存后的占用仅为173.9MB,且相对于原来pd.read_csv的7.7s的loading time,读入优化后的预处理数据文件能很大程度上的加速了读取。

Reference

[1].https://www.kaggle.com/arjanso/reducing-dataframe-memory-size-by-65

[2].https://zhuanlan.zhihu.com/p/56541628

[3].https://blog.csdn.net/weiyongle1996/article/details/78498603

GitHub:

[1] GitHub: https://github.com/lixiangwang/optimization-of-pandas-for-large-CSV

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员郭震zhenguo 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 内存优化
  • 2. 采用压缩格式存储
  • 3. 优化效果展示
    • Reference
      • GitHub:
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档