NumPy提供了多种文件操作函数方便我们存取数组内容。文件存取的格式分为两类:二进制和文本。
而二进制格式的文件又分为NumPy专用的格式化二进制类型和无格式类型。
1、二进制格式——无格式类型(fromfile()、tofile())
使用数组的方法函数tofile可以方便地将数组中数据以二进制的格式写进文件。tofile输出的数据没有格式,因此用numpy.fromfile读回来的时候需要自己格式化数据:
示例1:
import numpy as np
a = np.arange(12)
print a
a.shape = (3, 4)
a.tofile('a.bin')
# b = np.fromfile('a.bin', dtype='float') 错误,写入与读出元素类型不符
print a.dtype
b = np.fromfile('a.bin', dtype=a.dtype)
print b
b.shape = (3, 4)
print b
输出:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
int32
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
从上面的例子可以看出,需要在读入的时候设置正确的dtype和shape才能保证数据一致。并且tofile函数不管数组的排列顺序是C语言格式的还是Fortran语言格式的,统一使用C语言格式输出。
此外如果fromfile和tofile函数调用时指定了sep关键字参数的话,数组将以文本格式输入输出。
2、二进制格式——专用的二进制格式(load、save、savez)
numpy.load和numpy.save函数以NumPy专用的二进制类型保存数据,这两个函数会自动处理元素类型和shape等信息,使用它们读写数组就方便多了,但是numpy.save输出的文件很难和其它语言编写的程序读入:
示例2:
a = np.arange(12)
print a
a.shape = (3, 4)
print a
np.save('a.npy', a)
b = np.load('a.npy')
print b
输出:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
如果你想将多个数组保存到一个文件中的话,可以使用numpy.savez函数。savez函数的第一个参数是文件名,其后的参数都是需要保存的数组,也可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为arr_0, arr_1, ...。savez函数输出的是一个压缩文件(扩展名为npz),其中每个文件都是一个save函数保存的npy文件,文件名对应于数组名。load函数自动识别npz文件,并且返回一个类似于字典的对象,可以通过数组名作为关键字获取数组的内容:
示例4:
a = np.arange(12)
b = np.array([2, 1, 3, 4])
c = np.sin(a)
print a
print b
print c
np.savez('result.npz', a, b, sin_array=c)
r = np.load('result.npz')
print r['arr_0']
print r['arr_1']
print r['sin_array']
输出:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[2 1 3 4]
[ 0. 0.84147098 0.90929743 0.14112001 -0.7568025 -0.95892427
-0.2794155 0.6569866 0.98935825 0.41211849 -0.54402111 -0.99999021]
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[2 1 3 4]
[ 0. 0.84147098 0.90929743 0.14112001 -0.7568025 -0.95892427
-0.2794155 0.6569866 0.98935825 0.41211849 -0.54402111 -0.99999021]
如果你用解压软件打开result.npz文件的话,会发现其中有三个文件:arr_0.npy, arr_1.npy, sin_array.npy,其中分别保存着数组a, b, c的内容。如果你用解压软件打开result.npz文件的话,会发现其中有三个文件:arr_0.npy, arr_1.npy, sin_array.npy,其中分别保存着数组a, b, c的内容。
3、文本格式——(savetxt()、loadtxt())
示例4:
a = np.arange(0, 12, 0.5).reshape(4, -1)
print a
np.savetxt('a.txt', a) # 默认以%18e格式保存, 默认分割符为空格
b = np.loadtxt('a.txt')
print b
np.savetxt('a_1.txt', a, '%d', delimiter=',') # 采用整数格式保存,默认分割符为逗号
b = np.loadtxt('a_1.txt', delimiter=',')
print b
输出:
[[ 0. 0.5 1. 1.5 2. 2.5]
[ 3. 3.5 4. 4.5 5. 5.5]
[ 6. 6.5 7. 7.5 8. 8.5]
[ 9. 9.5 10. 10.5 11. 11.5]]
[[ 0. 0.5 1. 1.5 2. 2.5]
[ 3. 3.5 4. 4.5 5. 5.5]
[ 6. 6.5 7. 7.5 8. 8.5]
[ 9. 9.5 10. 10.5 11. 11.5]]
[[ 0. 0. 1. 1. 2. 2.]
[ 3. 3. 4. 4. 5. 5.]
[ 6. 6. 7. 7. 8. 8.]
[ 9. 9. 10. 10. 11. 11.]]
扩展——文件名与文件对象:
本节介绍所举的例子都是传递的文件名,也可以传递已经打开的文件对象,例如对于load和save函数来说,如果使用文件对象的话,可以将多个数组储存到一个npy文件中:
示例5:
a = np.arange(3)
b = np.array([4, 2, 3])
c = a + b
print a
print b
print c
f = open('1.npy', 'wb+')
np.save(f, a)
np.save(f, b)
np.save(f, c)
f.close()
print
f = open('1.npy', 'rb+')
d = np.load(f)
e = np.load(f)
g = np.load(f)
f.close()
print d
print e
print g
输出:
[0 1 2]
[4 2 3]
[4 3 5]
[0 1 2]
[4 2 3]
[4 3 5]
参考资料:
http://old.sebug.net/paper/books/scipydoc/numpy_intro.html
https://docs.scipy.org/doc/numpy/reference/routines.io.html