看了一下,前面的回答都不太对。把自己写的一篇文章贴上来吧。欢迎指正。
两个问题分别为多维数据存储和多维数据操作,是数据分析和机器学习的科研工作中最常遇见的问题。 常见的多维度数据有:真彩图、遥感影像图、医学影像图,最近比较火的深度图等等。
多维数据的特点:数据量大,单个数据最少也是(1000,1000,10)这个量级的。
矩阵形式
在存储的时候,需要考虑多个方面的问题:要对数据进行压缩。如果存储为常见的文本格式,单个数据动不动就是10多个G,绝对不行
存储以后,可以分片读取。否则想读取数据中的一小块数据,也要把所有的数据读取到内存中进行检索,这也是不行的
储存格式要通用。否则业务上游做好了数据,业务下游在使用的时候,会有很大的障碍
数据可以通过工具可视化查看。
库的安装使用方便。不要动不动就让科研工作者玩Hadoop,Spark好吧。。。
最优解决方案
HDF5的优点Python库安装方便。Anaconda中已经集成了,装好Anaconda,你就有了h5py这个库
格式通用。也是Pytorch中推荐的多维数据保存格式,使用h5py读取的数据,直接就是numpy.ndarray类
可视化。可以在官网下载HDF5的HDFViewer软件,直接打开文件进行查看。
数据压缩。按经验,一个保存为TXT格式需要2G空间的数据,使用HDF5只需要几十MB,节省了几十倍的空间
分片读取。不需要将数据全部读取到内存进行检索,直接可以使用切片操作读取,其他不需要的数据就不会被读取到内存
HDF5的常用操作,基于Python的h5py和numpy
数据拼接
首先回答第二个问题,如何拼接多维数据。
import numpy as np
# 创建(3, 1, 2)维度的矩阵
shape1 = (3, 1, 2)
a = np.zeros(shape1, dtype=np.int)
print(a.shape) # (3, 1, 2)
# 创建(4, 1, 2)维度的矩阵
shape2 = (4, 1, 2)
b = np.ones(shape2, dtype=np.int)
print(b.shape) # (4, 1, 2)
# 在第一个维度上拼接a和c
axis = 0 # axis指的是你想在第几个维度上进行拼接,因为numpy是0-base,所以第一个维度其实是0
c = np.concatenate((a, b), axis=axis)
print(c.shape) # (7, 1, 2)
储存为HDF5格式
import h5py
with h5py.File("c.hdf5", 'w') as f: # 写入的时候是‘w’
f.create_dataset("a_data", data=a, compression="gzip", compression_opts=5)
f.create_dataset("b_data", data=b, compression="gzip", compression_opts=5)
f.create_dataset("c_data", data=c, compression="gzip", compression_opts=5)
# c_data:是HDF5文件中c数据储存的名字
# compression="gzip":是对数据进行压缩,压缩的方式一个gzip
# compression_opts=5:是压缩等级,压缩等级越高,压缩的越好,但是压缩消耗的CPU时间会增加
读取HDF5格式文件中的数据
with h5py.File("c.hdf5", 'r') as f: # 读取的时候是‘r’
print(f.keys())
a_new = f.get("a_data")[:]
b_new = f.get("b_data")[:]
c_new = f.get("c_data")[:]
验证一下写入的数据和读取的数据是不是一样
print(a == a_new)
print(b == b_new)
print(c == c_new)
对比一下存储一个(5000, 5000)的数据,省多少空间,数据INT
import os
import numpy as np
data_5000_5000 = np.arange(0, 5000*5000, dtype=np.int).reshape(5000, 5000)
print(data_5000_5000)
[[ 0 1 2 ... 4997 4998 4999] [ 5000 5001 5002 ... 9997 9998 9999] [ 10000 10001 10002 ... 14997 14998 14999] ... [24985000 24985001 24985002 ... 24989997 24989998 24989999] [24990000 24990001 24990002 ... 24994997 24994998 24994999] [24995000 24995001 24995002 ... 24999997 24999998 24999999]]
使用TXT
np.savetxt("data.txt", data_5000_5000)
print(os.path.getsize("data.txt") / 1024 / 1024)
596.0512161254883 MB
使用HDF5
with h5py.File("data.hdf5", 'w') as f:
f.create_dataset("data", data=data_5000_5000, compression="gzip", compression_opts=5)
33.43095302581787 MB
结论
可以看到,使用TXT格式保存使用了596.05MB,使用HDF5格式保存使用了33.43MB。
596.05 / 33.43
17.829793598564162 节省了大概17倍的空间【数据分析】【Python】多维数据高效操作、读取与储存-numpy、h5py实现blog.csdn.net