别再用CSV了,更高效的Python文件存储方案
2021/8/14 22:05:53
本文主要是介绍别再用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') # 读取 df = feather.read_feather('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文件存储方案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-14获取参数学习:Python编程入门教程
- 2024-11-14Python编程基础入门
- 2024-11-14Python编程入门指南
- 2024-11-13Python基础教程
- 2024-11-12Python编程基础指南
- 2024-11-12Python基础编程教程
- 2024-11-08Python编程基础与实践示例
- 2024-11-07Python编程基础指南
- 2024-11-06Python编程基础入门指南
- 2024-11-06怎么使用python 计算两个GPS的距离功能-icode9专业技术文章分享