本文将通过pandas to_pickle()方法压缩文件,并比较不同格式压缩文件的大小、写入速度、读取速度,对比结果将说明哪种压缩文件最优。
学过Python基础的同学肯定知道有一个叫Pickle的模块,用来对数据进行序列化及反序列化。
对数据进行反序列化有什么用呢?一个重要的作用就是便于存储。
序列化过程将文本信息转变为二进制数据流,同时保存数据类型。比如,数据处理过程中,突然有事要走,你可以直接将数据序列化到本地,这时候你的数据是什么类型,保存到本地也是同样的数据类型,再次打开的时候同样也是该数据类型,而不是从头开始再处理。
导入库及数据
import pandas as pd
import numpy as np
import os
import re
data = pd.read_csv('qdaily_infos.csv',header=0)
查看文件本地文件大小
os.stat('qdaily_infos.csv').st_size/(1024 * 1024)
out:
19.07578182220459
使用to_pickle()方法进行文件压缩
read_pickle(),DataFrame.to_pickle()和Series.to_pickle()可以读取和写入压缩的腌制文件。 支持读写gzip,bz2,xz压缩类型。 zip文件格式仅支持读取,并且只能包含一个要读取的数据文件。 压缩类型可以是显式参数,也可以从文件扩展名推断出来。 如果为“infer”,则文件名分别以“ .gz”,“。bz2”,“。zip”或“ .xz”结尾。
直接保存为Pickle文件
data.to_pickle('qdaily_infos.pkl')
os.stat('qdaily_infos.pkl').st_size/(1024 * 1024)
out:
11.89148235321045
可以看到比原文件小了7.2M.
通过compression参数指定压缩类型
save_path_compress = ['qdaily_gzip.pkl.compress','qdaily_bz2.pkl.compress','qdaily_xz.pkl.compress']
compression = ['gzip','bz2','xz']
for path,compress in zip(save_path_compress,compression):
data.to_pickle(path,compression=compress)
print('the size of {0} is : {1}'.format(path,os.stat(path).st_size/(1024 * 1024)))
out:
the size of qdaily_gzip.pkl.compress is : 4.289911270141602
the size of qdaily_bz2.pkl.compress is : 3.002878189086914
the size of qdaily_xz.pkl.compress is : 2.890697479248047
通过文件后缀定义压缩类型
save_path_infer = ['qdaily.pkl.gzip','qdaily.pkl.bz2','qdaily.pkl.xz']
for path in save_path_infer:
data.to_pickle(path,compression='infer')
print('The size of {0} is : {1}'.format(path,os.stat(path).st_size/(1024 * 1024)))
out:
The size of qdaily.pkl.gzip is : 11.89148235321045
The size of qdaily.pkl.bz2 is : 3.002878189086914
The size of qdaily.pkl.xz is : 2.890697479248047
综合对比
path_all = save_path_compress + save_path_infer
path_all.insert(0,'qdaily_infos.pkl')
path_all.insert(0,'qdaily_infos.csv')
本地文件大小对比
for path in path_all:
print('The size of {0} is : {1}'.format(path,os.stat(path).st_size/(1024 * 1024)))
out:
The size of qdaily_infos.csv is : 19.07578182220459
The size of qdaily_infos.pkl is : 11.89148235321045
The size of qdaily_gzip.pkl.compress is : 4.289911270141602
The size of qdaily_bz2.pkl.compress is : 3.002878189086914
The size of qdaily_xz.pkl.compress is : 2.890697479248047
The size of qdaily.pkl.gzip is : 11.89148235321045
The size of qdaily.pkl.bz2 is : 3.002878189086914
The size of qdaily.pkl.xz is : 2.890697479248047
写入时间对比
for path in path_all:
if path.endswith('.csv'):
%time data.to_csv(path)
elif path.endswith('.pkl'):
%time data.to_pickle(path)
elif path.find('_') > 0:
compress = re.findall('_(.*?)\.',path)[0]
%time data.to_pickle(path,compression=compress)
else:
%time data.to_pickle(path,compression='infer')
out:
Wall time: 502 ms
Wall time: 62.8 ms
Wall time: 3.31 s
Wall time: 1.04 s
Wall time: 10.9 s
Wall time: 56.8 ms
Wall time: 1.02 s
Wall time: 10.7 s
读取时间对比
for path in path_all:
if path.endswith('.csv'):
%time pd.read_csv(path)
elif path.endswith('.pkl'):
%time pd.read_pickle(path)
elif path.find('_') > 0:
compress = re.findall('_(.*?)\.',path)[0]
%time pd.read_pickle(path,compression=compress)
else:
%time pd.read_pickle(path,compression='infer')
out:
Wall time: 369 ms
Wall time: 66.9 ms
Wall time: 122 ms
Wall time: 431 ms
Wall time: 401 ms
Wall time: 60.8 ms
Wall time: 450 ms
Wall time: 383 ms
结论
压缩效果最好的是xz格式,只有原来的15%,但是写入速度最慢;
写入速度最快的是gzip格式,只有56.8ms,同时也是读取速度最快的,60.8ms,但是压缩效果差一些,是原来的62%;
综合压缩效果、写入时间及读取时间,比较合适的压缩格式为.bz2格式,压缩效果为15.7%,写入速度会差一些,但是可以接受。
| | size | writing_time | read_time |
|:-------------------------|-------:|:---------------|:------------|
| qdaily_infos.csv | 19.08 | 502 ms | 369 ms |
| qdaily_infos.pkl | 11.89 | 62.8 ms | 66.9 ms |
| qdaily_gzip.pkl.compress | 4.28 | 3.31 s | 122 ms |
| qdaily_bz2.pkl.compress | 3 | 1.04 s | 431 ms |
| qdaily_xz.pkl.compress | 2.89 | 10.9 s | 401 ms |
| qdaily.pkl.gzip | 11.89 | 56.8 ms | 60.8 ms |
| qdaily.pkl.bz2 | 3 | 1.02 s | 450 ms |
| qdaily.pkl.xz | 2.89 | 10.7 s | 383 ms |