将 numpy 数组存入文件,有多种文件类型可供选择,对应地就有不同的方法来读写。

下面我将介绍读写 numpy 的三类文件:

  • txt 或者 csv 文件
  • npy 或者 npz 文件
  • hdf5 文件

通过 numpy 读写 txt 或 csv 文件

import numpy as np

a = np.array(range(20)).reshape((4, 5))
print(a) # 后缀改为 .txt 一样
filename = 'data/a.csv'
# 写文件
np.savetxt(filename, a, fmt='%d', delimiter=',') # 读文件
b = np.loadtxt(filename, dtype=np.int32, delimiter=',')
print(b)

缺点:

  • 只能保存一维和二维 numpy 数组,当 numpy 数组 a 有多维时,需要将其 a.reshape((a.shape[0], -1)) 后才能用这种方式保存。
  • 不能追加保存,即每次 np.savetxt() 都会覆盖之前的内容。

通过 numpy 读写 npy 或 npz 文件

读写 npy 文件

import numpy as np

a = np.array(range(20)).reshape((2, 2, 5))
print(a) filename = 'data/a.npy'
# 写文件
np.save(filename, a) # 读文件
b = np.load(filename)
print(b)
print(b.shape)

优点:

  • npy 文件可以保存任意维度的 numpy 数组,不限于一维和二维;
  • npy 保存了 numpy 数组的结构,保存的时候是什么 shape 和 dtype,取出来时就是什么样的 shape 和 dtype。

缺点:

  • 只能保存一个 numpy 数组,每次保存会覆盖掉之前文件中存在的内容(如果有的话)。

读写 npz 文件

import numpy as np

a = np.array(range(20)).reshape((2, 2, 5))
b = np.array(range(20, 44)).reshape(2, 3 ,4)
print('a:\n', a)
print('b:\n', b) filename = 'data/a.npz'
# 写文件, 如果不指定key,那么默认key为'arr_0'、'arr_1',一直排下去。
np.savez(filename, a, b=b) # 读文件
c = np.load(filename)
print('keys of NpzFile c:\n', c.keys())
print("c['arr_0']:\n", c['arr_0'])
print("c['b']:\n", c['b'])

优点:

  • npy 文件可以保存任意维度的 numpy 数组,不限于一维和二维;
  • npy 保存了 numpy 数组的结构,保存的时候是什么 shape 和 dtype,取出来时就是什么样的 shape 和 dtype;
  • 可以同时保存多个 numpy 数组;
  • 可以指定保存 numpy 数组的 key,读取的时候很方便,不会混乱。

缺点:

  • 保存多个 numpy 数组时,只能同时保存,即 np.savez(filename, a, b=b)。每次保存会覆盖掉之前文件中存在的内容(如果有的话)。

通过 h5py 读写 hdf5 文件

优点:

  • 不限 numpy 数组维度,可以保持 numpy 数组结构和数据类型;
  • 适合 numpy 数组很大的情况,文件占用空间小;
  • 可以通过 key 来访问 dataset(可以理解为 numpy.array),读取的时候很方便,不会混乱。
  • 可以不覆盖原文件中含有的内容。

简单读取

import numpy as np
import h5py a = np.array(range(20)).reshape((2, 2, 5))
b = np.array(range(20)).reshape((1, 4, 5))
print(a)
print(b) filename = 'data/data.h5'
# 写文件
h5f = h5py.File(filename, 'w')
h5f.create_dataset('a', data=a)
h5f.create_dataset('b', data=b)
h5f.close() # 读文件
h5f = h5py.File(filename, 'r')
print(type(h5f))
# 通过切片得到numpy数组
print(h5f['a'][:])
print(h5f['b'][:])
h5f.close()

通过切片赋值

import numpy as np
import h5py a = np.array(range(20)).reshape((2, 2, 5))
print(a) filename = 'data/a.h5'
# 写文件
h5f = h5py.File(filename, 'w')
# 当数组a太大,需要切片进行操作时,可以不直接对h5f['a']进行初始化;
# 当之后不需要改变h5f['a']的shape时,可以省略maxshape参数
h5f.create_dataset('a', shape=(2, 2, 5), maxshape=(None, 2, 5), dtype=np.int32, compression='gzip')
for i in range(2):
# 采用切片的形式赋值
h5f['a'][i] = a[i]
h5f.close() # 读文件
h5f = h5py.File(filename, 'r')
print(type(h5f))
print(h5f['a'])
# 通过切片得到numpy数组
print(h5f['a'][:])

同一个 hdf5 文件可以创建多个 dataset,读取的时候按照 key 来即可。

总结

  • csv 和 txt 只能用来存一维或二维 numpy 数组;
  • npy 用来存单个 numpy 数组,npz 可以同时存多个 numpy 数组,两者都不限 numpy 维度,且都保持 numpy 数组的 shape 和 dtype,写文件时若原文件存在只能覆盖原文件内容;
  • 当 numpy 数组很大时,最好使用 hdf5 文件,hdf5 文件相对更小;
  • 当 numpy 数组很大时,对整个 numpy 数组进行运算容易发生 MemoryError,那么此时可以选择对 numpy 数组切片,将运算后的数组保存到 hdf5 文件中,hdf5 文件支持切片索引。

References

当Python遇上HDF5--性能优化实战 -- 张玉腾

杂: PYTHON上数据储存:推荐h5py -- Pony_s

numpy数组之读写文件的更多相关文章

  1. python:将numpy数组写入csv文件

    import numpy as np np.savetxt('E:\\forpython\\featvector.csv',data_to_save,delimiter=',')

  2. python : 将txt文件中的数据读为numpy数组或列表

    很多时候,我们将数据存在txt或者csv格式的文件里,最后再用python读取出来,存到数组或者列表里,再做相应计算.本文首先介绍写入txt的方法,再根据不同的需求(存为数组还是list),介绍从tx ...

  3. numpy数组与python的list互转,然后用json写入文件与c交互

    1.对于numpy的tofile方法,一个一维数组可以直接写成二进制形式,用c语言或者numpy.fromfile()可以读出来内容.而如果数组超过一维,tofile并不区分,也就是arr1=[1,2 ...

  4. java读写文件小心缓存数组

    一般我们读写文件的时候都是这么写的,看着没问题哈.   public static void main(String[] args) throws Exception {   FileInputStr ...

  5. 玩转NumPy数组

    一.Numpy 数值类型 1.前言:Python 本身支持的数值类型有 int(整型, long 长整型).float(浮点型).bool(布尔型) 和 complex(复数型).而 Numpy 支持 ...

  6. 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库

    57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...

  7. C语言读写文件

    对文件的读和写是最常用的文件操作.在C语言中提供了多种文件读写的函数: 字符读写函数  :fgetc和fputc 字符串读写函数:fgets和fputs 数据块读写函数:freed和fwrite 格式 ...

  8. C#常用IO流与读写文件

    .文件系统 ()文件系统类的介绍 文件操作类大都在System.IO命名空间里.FileSystemInfo类是任何文件系统类的基类:FileInfo与File表示文件系统中的文件:Directory ...

  9. java读写文件大全

     java读写文件大全 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类,这两个类都是抽象类,Writer中 write(char[] ch,int o ...

随机推荐

  1. C++ C++ 值传递、指针传递、引用传递详解

    这一篇博客写的不错: https://www.cnblogs.com/dingxiaoqiang/p/8012578.html

  2. shell脚本,如何写进度条。

    [root@localhost ~]# cat jindutiao.sh #!/bin/bash #进度条 n=$((/)) N=$((/)) ` do sleep 0.01 [ $(($i%$n)) ...

  3. javase(5)_面向对象

    一.概述 1.面向对象是一种思想,让我们由执行者变成指挥者,执行者是面向过程,指挥者是面向对象.例如人开冰箱门,开冰箱门这个动作应该属于门而不是人,冰箱自己最清楚门应该怎么开,人只是调用了冰箱的这个动 ...

  4. (62)zabbix客户端自动注册

    1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中. 我们本篇内容与上篇相反,这次是Active ag ...

  5. SQL server的GO用法--巨坑

    SQL脚本是一种用SQL语言写的批处理文件(.sql),SQL脚本通常可以由SQL查询分析器来执行. ================================================= ...

  6. 递归函数&二分查找

    一.递归函数 1)定义 在函数中调用函数本身,就是递归 在python中递归的深度最大为1000,但实际达不到1000 def func(): print("-----func-----&q ...

  7. 双线性差值(由于分析sift源码 )

    双线性插值 双线性插值,顾名思义就是两个方向的线性插值加起来.所以只要了解什么是线性插值,分别在x轴和y轴都做一遍,就是双线性插值了. 线性插值的概念也非常简单粗暴,就是两个点A,B,要在AB中间插入 ...

  8. 排序算法C语言实现——堆排序

    /*堆排nlog(n)*//*堆排复杂度分析1.建堆((n*log(n))/2)    循环n/2次,每次调用HeapAdjust函数    HeapAdjust内部循环log(n)2.调整堆(((n ...

  9. !!注意!部署出现the requested resource is not available

    避免项目里重复包出现 同时tomcat的lib里避免重复包,也会出现requested resource isnot available!

  10. nw.js学习地址

    http://blog.sina.com.cn/s/blog_600e56a60102vqj2.html https://github.com/nwjs/nw.js/wiki/Manifest-For ...