归纳一下python中不同数据保存格式的存储和读取,旨在方法整理和速度比较。
从数据角度分两种,一是ndarray格式的纯数值数据的读写,二是对象(数据结构)如dict的文件存取。
import numpy as np
a = np.random.randint(0, 100, size=(10000, 5000))
print(a.dtype, a.shape) # int32 (10000, 5000) 下同
a.tofile('data/a.bin')
b = np.fromfile('data/a.bin', dtype=np.int32) # 需要设置正确dtype
print(b.shape) # (50000000,) 读入数据是一维的,需要reshape
np.save('data/a.npy', a)
b = np.load('data/a.npy')
print(b.shape) # (10000, 5000)
np.savetxt('data/a.txt', a, fmt='%d', delimiter=',') #设置以整数存储,以逗号隔开
b = np.loadtxt('data/a.txt', delimiter=',')
print(b.shape) # (10000, 5000)
import h5py
f = h5py.File('data/a.h5','w') #创建一个h5文件,文件指针是f
f['data'] = a #将数据写成data的键值
f.close() #关闭文件
f = h5py.File('data/a.h5','r') #打开h5文件
# print f.keys() #查看所有的键
b = f['data'][:] #取出键名为data的键值
f.close()
print(b.shape) # (10000, 5000)
至于h5py的安装,Unix/Linux系统参考这篇 PYTHON上数据储存:推荐h5py
Windows系统在这里下载h5py.whl
几种方法存储读取耗时:
格式 | 文件大小 | 存储耗时 | 读取耗时 | 备注 |
---|---|---|---|---|
a.bin | 190MB | 1.130s | 0.110s | 需要处理type和reshape |
a.npy | 190MB | 1.105s | 0.124s | |
a.txt | 138MB | 10.507s | 60.225s | 需要处理type |
a.h5 | 190MB | 1.026s | 0.122s | |
a.pkl | 190MB | 1.295s | 0.253s |
以上参考:http://blog.csdn.net/jerr__y/article/details/74230765
序列化,把对象(数据结构)序列化成字符串,可以存储在文件中,也就是对象的持久化
反序列化,序列化的反向操作,把经过序列化的对象(数据结构)加载到内存
python中有个两个序列化模块:json 和 pickle
也正是python两个相对轻量级的数据持久化方式。
import json
raw_dict = {'key1': 'value1', 'key2': 'value2'} #
wf = open('save', 'w') # 将dict类型对象序列化存储到文件中
json.dump(obj=raw_dict, fp=wf)
rf = open('save') # 将文件中的数据反序列化成内置的dict类型
raw_data = json.load(fp=rf)
print(raw_data) # 输出{'key1': 'value1', 'key2': 'value2'}
import pickle
#python2有个cpickle模块是用c实现的pickle,速度较快,在python3中已改为了pickle
raw_dict = {'key1': 'value1', 'key2': 'value2'}
wf = open('save.pkl', 'wb') # 将dict类型对象序列化存储到文件中
pickle.dump(obj=raw_dict, file=wf)
rf = open('save.pkl', 'rb')
raw_data = pickle.load(file=rf) # 将文件中的数据反序列化成内置的dict类型
print(raw_data) # 输出{'key1': 'value1', 'key2': 'value2'}
序列化到 ‘save’文件中的对象是这样的:
{"key1": "value1", "key2": "value2"}
而序列化到 ‘save.pkl’文件中是这样的:
8003 7d71 0028 5804 0000 006b 6579 3171
0158 0600 0000 7661 6c75 6531 7102 5804
0000 006b 6579 3271 0358 0600 0000 7661
6c75 6532 7104 752e
存储了几个对象就只能load几次,如果load超过了存储的对象,会抛出EOFError异常。
这里能够存储的对象可以是任意对象,字典、列表、元组、numpy数组等。
二者的区别:
但是因为pkl的存取速度比json还要慢,有时存储较大的训练数据库(几G)这种情况,不存对象直接把内容存成明文(一般的文本文件)也要比存pkl好。
参考:Pickle vs JSON — Which is Faster?
补充:
pandas官网也给python提供了较全的读取文件不同格式的方法
读取存储csv格式文件:
pd.read_csv() df.to_csv()
读取存储json格式文件:
pd.read_json() df.to_json()
读网页中的表格:
pd.read_html() df.to_html()
读取xls文件,有excel版本限制;存储时数据要先存成DataFrame:
pd.read_excel() pd.to_excel()
读取存储pickle格式文件:
pd.read_pickle('foo.pkl') df.to_pickle('foo.pkl')
读取存储为HDFS文件:
pd.HDFStore("store.h5")
df.to_hdf()
pd.read_hdf()
这些函数的参数都可以有多样参数设置,具体用法查阅pandas官网文档