python相关的几种数据类型的存储读取方式

归纳一下python中不同数据保存格式的存储和读取,旨在方法整理和速度比较。

从数据角度分两种,一是ndarray格式的纯数值数据的读写,二是对象(数据结构)如dict的文件存取。

数值数据的读写

  • .bin格式,np.tofile() 和 np.fromfile()
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
  • .npy格式,np.save() 和 np.load()
    numpy专用的二进制格式保存数据,能自动处理变量type和size
np.save('data/a.npy', a)
b = np.load('data/a.npy')
print(b.shape)           # (10000, 5000)
  • .txt格式 (或.csv/.xlsx),np.savetxt() 和 np.loadtxt()
    csv或xlsx可以借助python其他库工具实现。csv只能存数字,xlsx可以存数字字符。
np.savetxt('data/a.txt', a, fmt='%d', delimiter=',') #设置以整数存储,以逗号隔开
b = np.loadtxt('data/a.txt', delimiter=',')
print(b.shape)           # (10000, 5000)
  • .h5格式,h5py.File(data, ‘r’ or ‘w’)
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
  • 存成bin还要处理类型和矩阵大小,繁琐
  • 存成txt或csv节省空间,但速度太慢
  • 使用np.save()和h5py的方法比较方便快捷,特别是h5py还能存字典对象,用处很大,所以被很多人推荐
  • json存储数据必须是可序列化对象,而pickle虽然能存数值矩阵a,但一般不这么用

以上参考: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数组等。

二者的区别:

  • JSON是文本形式的存储,Pickle则是二进制形式(至少常用二进制)
  • JSON是人可读的,Pickle不可读
  • JSON广泛应用于除Python外的其他领域,Pickle是Python独有的
  • JSON只能dump一些python的内置对象,Pickle可以存储几乎所有对象
  • 如果偏向应用特别是web应用,可以常用JSON格式,如果偏向算法,尤其是机器学习,则通常使用cPickle,pylearn2库中保存model就是使用这项技术的

但是因为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官网文档


你可能感兴趣的:(Python)