别再用CSV了,更高效的Python文件存储方案
CSV无可厚非的是一种良好的通用文件存储方式,几乎任何一款工具或者编程语言都能对其进行读写,但是当文件特别大的时候,CSV这种存储方式就会变得十分缓慢且低效。本文将介绍几种在Python中能够代替CSV这种格式的其他文件格式,并对比每种文件存储的时间与大小。
先说结论,parquet
是最好的文件存储格式,具体对比见下文。
生成随机数据
导入依赖
import random
import string
import pickle
# 以下需要自行安装
import numpy as np
import pandas as pd
import tables
import pyarrow as pa
import pyarrow.feather as feather
import pyarrow.parquet as pq
生成随机数据
这里使用pandas的dataframe来存储数据
# 变量定义
row_num = int(1e7)
col_num = 5
str_len = 4
str_nunique = 10 # 字符串组合数量
# 生成随机数
int_matrix = np.random.randint(0, 100, size=(row_num, col_num))
df = pd.DataFrame(int_matrix, columns=['int_%d' % i for i in range(col_num)])
float_matrix = np.random.rand(row_num, col_num)
df = pd.concat(
(df, pd.DataFrame(float_matrix, columns=['float_%d' % i for i in range(col_num)])), axis=1)
str_list = [''.join(random.sample(string.ascii_letters, str_len))
for _ in range(str_nunique)]
for i in range(col_num):
sr = pd.Series(str_list*(row_num//str_nunique)
).sample(frac=1, random_state=i)
df['str_%d' % i] = sr
print(df.info())
生成100w行数据,其中整型,浮点型和字符串各5列,数据大小在内存里大概为1GB+
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000000 entries, 0 to 9999999
Data columns (total 15 columns):
# Column Dtype
--- ------ -----
0 int_0 int64
1 int_1 int64
2 int_2 int64
3 int_3 int64
4 int_4 int64
5 float_0 float64
6 float_1 float64
7 float_2 float64
8 float_3 float64
9 float_4 float64
10 str_0 object
11 str_1 object
12 str_2 object
13 str_3 object
14 str_4 object
dtypes: float64(5), int64(5), object(5)
memory usage: 1.1+ GB
保存文件
csv
CSV的保存方式很简单,直接使用pandas自带的to_csv()
方法即可
# 写入
df.to_csv('./df_csv.csv', index=False)
# 读取
df = pd.read_csv('./df_csv.csv')
写入时间花费:78 s
读取时间花费:11.8 s
所需存储空间:1.3GB
pkl
pkl文件需要用到built-in
的pickle
包
# 写入
with open('./df_pkl.pkl', 'wb') as f:
pickle.dump(df, f)
# 读取
with open('./df_pkl.pkl', 'rb') as f:
df = pickle.load(f)
写入时间花费:2.89 s
读取时间花费:2.61 s
所需存储空间:858M
npy
npy是numpy自带的一种保存格式,唯一的缺点是只能保存numpy的格式,所以需要将pandas先转成numpy才行,为了公平,这里我们会算上转换的时间
# 写入
with open('./df_npy.npy', "wb") as f:
np.save(f, arr=df.values)
# 读取
with open('./df_npy.npy', "rb") as f:
df_array = np.load(f, allow_pickle=True)
df = pd.DataFrame(df_array)
写入时间花费:21 s
读取时间花费:14.8 s
所需存储空间:620M
hdf
层次数据格式(HDF)是自描述的,允许应用程序在没有外部信息的情况下解释文件的结构和内容。一个HDF文件可以包含一系列相关对象,这些对象可以作为一个组或单个对象进行访问。
这里将使用pandas自带的to_hdf()
方法,该方法默认是用的HDF5
格式
# 写入
df.to_hdf('df_hdf.h5', key='df')
# 读取
df = pd.read_hdf('df_hdf.h5', key='df')
写入时间花费:3.96 s
读取时间花费:4.13 s
所需存储空间:1.5G
已废弃 msgpack
pandas支持msgpack格式的对象序列化。他是一种轻量级可移植的二进制格式,同二进制的JSON类似,具有高效的空间利用率以及不错的写入(序列化)和读取(反序列化)性能。
从0.25版本开始,不推荐使用msgpack格式,并且之后的版本也将删除它。推荐使用pyarrow对pandas对象进行在线的转换。
read_msgpack() (opens new window)仅在pandas的0.20.3版本及以下版本兼容。
parquet
Apache Parquet为数据帧提供了分区的二进制柱状序列化。它的设计目的是使数据帧的读写效率,并使数据共享跨数据分析语言容易。Parquet可以使用多种压缩技术来尽可能地缩小文件大小,同时仍然保持良好的读取性能。
这里需要使用到pyarrow
里面的方法来进行操作
# 写入
pq.write_table(pa.Table.from_pandas(df), 'df_parquet.parquet')
# 读取
df = pq.read_table('df_parquet.parquet').to_pandas()
写入时间花费:3.47 s
读取时间花费:1.85 s
所需存储空间:426M
feature
Feather是一种可移植的文件格式,用于存储内部使用Arrow IPC格式的Arrow表或数据帧(来自Python或R等语言)。Feather是在Arrow项目早期创建的,作为Python和R的快速、语言无关的数据帧存储概念的证明。
这里需要使用到pyarrow
里面的方法来进行操作
# 写入
feather.write_feather(df, 'df_feather.feather')
# 读取
写入时间花费:1.9 s
读取时间花费:1.52 s
所需存储空间:715M
总结
对比表格
文件类型 | 读取时间(s) | 写入时间(s) | 存储空间(MB) |
---|---|---|---|
csv | 78.00 | 11.80 | 1,300 |
pickle | 2.89 | 2.61 | 858 |
npy | 21.00 | 14.80 | 620 |
hdf | 3.96 | 4.13 | 1,500 |
parquet | 3.47 | 1.85 | 426 |
feature | 1.90 | 1.52 | 715 |
时间对比
空间对比
可以看出parquet
会是一个保存文件的最好选择,虽然时间上比feature
略慢一点,但空间上有着更大的优势。
别再用CSV了,更高效的Python文件存储方案的更多相关文章
- 【数据处理】SQL Server高效大数据量存储方案SqlBulkCopy
要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储. 一个比较好的解决方案,就是采用SqlBulkCopy来处理存储数据. SqlBulkCopy存储大批量的数 ...
- 如何使代码审查更高效【摘自InfoQ】
代码审查者在审查代码时有非常多的东西需要关注.一个团队需要明确对于自己的项目哪些点是重要的,并不断在审查中就这些点进行检查. 人工审查代码是十分昂贵的,因此尽可能地使用自动化方式进行审查,如:代码 ...
- LocalBroadcastManager—创建更高效、更安全的广播
前言 在写Android应用时候,有时候或多或少的需要运用广播来解决某些需求,我们知道广播有一个特性,就是使用sendBroadcast(intent);发送广播时,手机内所有注册了Broadcast ...
- 这些小工具让你的Android 开发更高效
在做Android 开发过程中,会遇到一些小的问题.尽管自己动手也能解决.可是有了一些小工具,解决这些问题就得心应手了,今天就为大家推荐一下Android 开发遇到的小工具,来让你的开发更高效. Vy ...
- Pull Request 工作流——更高效的管理代码
目录 Pull Request 工作流--更高效的管理代码 1.问题 2.解决方案 3.Git分支流管理代码具体实施 3.1本地分支操作管理 3.1.1查看分支 3.1.2创建分支 3.1.3切换分支 ...
- CesiumLab V1.4 分类3dtiles生成(倾斜单体化、楼层房间交互)我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了。不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化。就下面这个示例https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=
我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了.不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化.就下面这个示例 http ...
- [源码解析]为什么mapPartition比map更高效
[源码解析]为什么mapPartition比map更高效 目录 [源码解析]为什么mapPartition比map更高效 0x00 摘要 0x01 map vs mapPartition 1.1 ma ...
- 阿里面试:MySQL如何设计索引更高效?
有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...
- 想要更高效地找到信息,你需要掌握这些搜索技巧 (google or baidu)
想要更高效地找到信息,你需要掌握这些搜索技巧 (google or baidu) 转载:https://tingtalk.me/search-tips/ 在大型局域网(互联网)的今天,你以为搜索是一门 ...
随机推荐
- Datahub 0.8.5发布! 通用的元数据搜索和发现工具
近期Datahub 发布了最新的版本0.8.5,作为LinkedIn开源的通用的元数据搜索和发现工具.Datahub近一年来有了巨大的发展,也成为了很多公司进行元数据管理的调研方向并进行使用的选择. ...
- 0、springboot
在线新建springboot项目 https://start.spring.io/ 参考地址 https://github.com/battcn/spring-boot2-learning 博客 ht ...
- XCTF GAME
首先这题有两种解法,一种是使用ida查看伪代码直接写exp跑出flag,另外一种是调试,因为最近在学调试,刚好用于实战上了. 一.查壳 二.32位文件拖入od动态调试 先找到game的主要函数,插件中 ...
- B站挂了之后出现的tengine是个啥?
一.描述 晚上刚洗漱完之后听同学说:B站挂了?woc?真挂了? 嗯!确实挂了,404的状态码,懂的都懂. 不过,最下面的tengine字眼吸引了我的注意,一时兴起,打算看看它是个什么东西,起码搞一个h ...
- 『心善渊』Selenium3.0基础 — 29、使用HTMLTestRunner生成unittest的HTML报告
目录 1.HTMLTestRunner介绍 2.HTMLTestRunner的使用 3.测试报告示例 4.封装成模块 1.HTMLTestRunner介绍 HTMLTestRunner是一个基于uni ...
- java基础---设计模式(3)
行为型模式 出处:http://blog.csdn.net/zhangerqing 行为型模式包括策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式 ...
- RWLock——一种细粒度的Mutex互斥锁
RWMutex -- 细粒度的读写锁 我们之前有讲过 Mutex 互斥锁.这是在任何时刻下只允许一个 goroutine 执行的串行化的锁.而现在这个 RWMutex 就是在 Mutex 的基础上进行 ...
- TCP/IP 5层协议簇/协议栈
TCP/IP 5层协议簇/协议栈 数据/PDU 应用层 PC.防火墙 数据段/段Fragment 传输层 防火墙 报文/包/IP包packet 网络层 路由器 帧Frame 数据链路层 交换机.网卡 ...
- Codeforces Round#687 Div2 题解
打这场的时候迷迷糊糊的,然后掉分了( A Prison Break: 题面很复杂,但是题意很简单,仅需求出从这个点到四个角的最大的曼哈顿距离即可 #include <bits/stdc++.h& ...
- C语言:地址
一切都是地址 C语言用变量来存储数据,用函数来定义一段可以重复使用的代码,它们最终都要放到内存中才能供 CPU 使用.数据和代码都以二进制的形式存储在内存中,计算机无法从格式上区分某块内存到底存储的是 ...