How to write a multidimensional array to a text file?
在另一个问题中,如果我能提供我遇到问题的阵列,其他用户会提供一些帮助。但是,我甚至在一个基本的I/O任务上失败,例如将数组写入一个文件。
有人能解释一下我需要什么样的循环来将4x11x14 numpy数组写入文件吗?
这个数组由四个11 x 14数组组成,所以我应该用一个漂亮的换行符来格式化它,以使其他数组更容易读取文件。
编辑:所以我尝试了numpy.savetxt函数。奇怪的是,它给出了以下错误:
1 | TypeError: float argument required, not numpy.ndarray |
我假设这是因为函数不适用于多维数组?有我想在一个文件中找到的解决方案吗?
如果你想把它写到磁盘上,这样它就可以很容易地作为一个numpy数组读回,那么可以查看
如果你想让它具有人类可读性,可以查看
编辑:所以,对于尺寸大于2的阵列来说,
我刚刚意识到
例如,这个(一个二维数组)工作正常
1 2 3 | import numpy as np x = np.arange(20).reshape((4,5)) np.savetxt('test.txt', x) |
同样的事情也会失败(有一个相当不具格式性的错误:
1 2 3 | import numpy as np x = np.arange(200).reshape((4,5,10)) np.savetxt('test.txt', x) |
。
一个解决方法是将3D(或更高版本)数组分解为二维切片。例如。
1 2 3 4 | x = np.arange(200).reshape((4,5,10)) with file('test.txt', 'w') as outfile: for slice_2d in x: np.savetxt(outfile, slice_2d) |
然而,我们的目标是清晰的人类可读性,同时仍然可以很容易地用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import numpy as np # Generate some test data data = np.arange(200).reshape((4,5,10)) # Write the array to disk with open('test.txt', 'w') as outfile: # I'm writing a header here just for the sake of readability # Any line starting with"#" will be ignored by numpy.loadtxt outfile.write('# Array shape: {0} '.format(data.shape)) # Iterating through a ndimensional array produces slices along # the last axis. This is equivalent to data[i,:,:] in this case for data_slice in data: # The formatting string indicates that I'm writing out # the values in left-justified columns 7 characters in width # with 2 decimal places. np.savetxt(outfile, data_slice, fmt='%-7.2f') # Writing out a break to indicate different slices... outfile.write('# New slice ') |
。
这将产生:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # Array shape: (4, 5, 10) 0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00 11.00 12.00 13.00 14.00 15.00 16.00 17.00 18.00 19.00 20.00 21.00 22.00 23.00 24.00 25.00 26.00 27.00 28.00 29.00 30.00 31.00 32.00 33.00 34.00 35.00 36.00 37.00 38.00 39.00 40.00 41.00 42.00 43.00 44.00 45.00 46.00 47.00 48.00 49.00 # New slice 50.00 51.00 52.00 53.00 54.00 55.00 56.00 57.00 58.00 59.00 60.00 61.00 62.00 63.00 64.00 65.00 66.00 67.00 68.00 69.00 70.00 71.00 72.00 73.00 74.00 75.00 76.00 77.00 78.00 79.00 80.00 81.00 82.00 83.00 84.00 85.00 86.00 87.00 88.00 89.00 90.00 91.00 92.00 93.00 94.00 95.00 96.00 97.00 98.00 99.00 # New slice 100.00 101.00 102.00 103.00 104.00 105.00 106.00 107.00 108.00 109.00 110.00 111.00 112.00 113.00 114.00 115.00 116.00 117.00 118.00 119.00 120.00 121.00 122.00 123.00 124.00 125.00 126.00 127.00 128.00 129.00 130.00 131.00 132.00 133.00 134.00 135.00 136.00 137.00 138.00 139.00 140.00 141.00 142.00 143.00 144.00 145.00 146.00 147.00 148.00 149.00 # New slice 150.00 151.00 152.00 153.00 154.00 155.00 156.00 157.00 158.00 159.00 160.00 161.00 162.00 163.00 164.00 165.00 166.00 167.00 168.00 169.00 170.00 171.00 172.00 173.00 174.00 175.00 176.00 177.00 178.00 179.00 180.00 181.00 182.00 183.00 184.00 185.00 186.00 187.00 188.00 189.00 190.00 191.00 192.00 193.00 194.00 195.00 196.00 197.00 198.00 199.00 # New slice |
。
只要我们知道原始数组的形状,就很容易读回它。我们只需要做一个
1 2 3 4 5 6 7 8 9 10 11 12 | # Read the array from disk new_data = np.loadtxt('test.txt') # Note that this returned a 2D array! print new_data.shape # However, going back to 3D is easy if we know the # original shape of the array new_data = new_data.reshape((4,5,10)) # Just to check that they're the same... assert np.all(new_data == data) |
我不确定这是否符合您的要求,因为我认为您有兴趣让人们阅读该文件,但如果这不是主要问题,只需
要保存它:
1 2 3 4 5 6 7 8 | import pickle my_data = {'a': [1, 2.0, 3, 4+6j], 'b': ('string', u'Unicode string'), 'c': None} output = open('data.pkl', 'wb') pickle.dump(my_data, output) output.close() |
要读回:
1 2 3 4 5 6 7 8 | import pprint, pickle pkl_file = open('data.pkl', 'rb') data1 = pickle.load(pkl_file) pprint.pprint(data1) pkl_file.close() |
号
如果您不需要一个人类可读的输出,您可以尝试的另一个选项是将数组保存为一个matlab
与JoeKington的答案不同,这样做的好处在于,您不需要知道
下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import numpy as np import scipy.io # Some test data x = np.arange(200).reshape((4,5,10)) # Specify the filename of the .mat file matfile = 'test_mat.mat' # Write the array to the mat file. For this to work, the array must be the value # corresponding to a key name of your choice in a dictionary scipy.io.savemat(matfile, mdict={'out': x}, oned_as='row') # For the above line, I specified the kwarg oned_as since python (2.7 with # numpy 1.6.1) throws a FutureWarning. Here, this isn't really necessary # since oned_as is a kwarg for dealing with 1-D arrays. # Now load in the data from the .mat that was just saved matdata = scipy.io.loadmat(matfile) # And just to check if the data is the same: assert np.all(x == matdata['out']) |
。
如果忘记了数组在
1 | print matdata.keys() |
当然,您可以使用更多的键来存储许多数组。
所以是的——用你的眼睛是看不懂的,但写和读数据只需要两行,我认为这是一个公平的权衡。
查看scipy.io.savemat的文档和scipy.io.loadmat还有这个教程页面:scipy.io文件IO教程
例如,如果您的数组名为
1 | a.tofile('yourfile.txt',sep="",format="%s") |
。
但不确定如何获取换行格式。
编辑(这里是Kevin J.Black的评论):
Since version 1.5.0,
np.tofile() takes an optional parameter
newline=' to allow multi-line output.
'
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.savetxt.html
号
有专门的图书馆可以做到这一点。(加上python的包装纸)
- netcdf4:http://www.unidata.ucar.edu/software/netcdf/
netcdf4 python接口:http://www.unidata.ucar.edu/software/netcdf/software.html python
HDF5:http://www.hdfgroup.org/hdf5/
小精灵
希望这有帮助
只需在三个嵌套循环中遍历数组,并将其值写入文件。对于阅读,您只需使用相同的精确循环结构。您将以正确的顺序获得值,以便再次正确地填充数组。
泡菜最适合这些情况。假设您有一个名为
1 2 3 4 5 6 7 8 9 | import pickle ###Load into file with open("myfile.pkl","wb") as f: pickle.dump(x_train,f) ###Extract from file with open("myfile.pkl","rb") as f: x_temp = pickle.load(f) |
号
我有一种方法可以使用一个简单的filename.write()操作来完成它。它对我来说很好,但是我处理的数组有大约1500个数据元素。
我基本上只需要for循环迭代文件,并以csv样式的输出将其逐行写入输出目标。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import numpy as np trial = np.genfromtxt("/extension/file.txt", dtype = str, delimiter =",") with open("/extension/file.txt","w") as f: for x in xrange(len(trial[:,1])): for y in range(num_of_columns): if y < num_of_columns-2: f.write(trial[x][y] +",") elif y == num_of_columns-1: f.write(trial[x][y]) f.write(" ") |
if和elif语句用于在数据元素之间添加逗号。无论出于什么原因,当以nd数组的形式读取文件时,这些都会被剥离出来。我的目标是将文件输出为csv,所以这个方法有助于处理这个问题。
希望这有帮助!