2010-09-10 124 views
79

在另外一个问题,其他用户提供一些帮助,如果我可以提供我是有麻烦的阵列。但是,我甚至在基本的I/O任务上失败,例如将数组写入文件。如何写一个多维数组到一个文本文件?

谁能解释我需要写一个4x11x14 numpy的阵列到文件什么样的循环?

这个数组由四个11×14的数组组成,所以我应该用一个漂亮的换行符来格式化它,以使其他文件的读取更容易。

编辑:所以我试过了numpy.savetxt函数。奇怪的是,它给出了以下错误:

TypeError: float argument required, not numpy.ndarray 

我假设这是因为该函数不适用于多维数组?任何解决方案,我想他们在一个文件中?

+0

对不起,在发布我的答案后重新阅读您的问题,并怀疑它不符合您的需求 - 如果没有,请将我平复,然后发布替代方案。 (很高兴在前四分之一btw的这部分看到你) – 2010-09-10 14:20:23

+0

其实 - 看起来像乔金顿的答案应该为你工作。 – 2010-09-10 14:21:28

回答

149

如果你想将其写入到磁盘,以便它会很容易在读回作为numpy的阵列,看看numpy.save。酸洗它也可以很好地工作,但是对于大型阵列来说它效率较低(这不是你的,所以或者是非常好的)。

如果你希望它是人类可读的,看看numpy.savetxt

编辑:所以,好像savetxt不用于> 2名维数组作为相当大的选择......但是,仅仅绘制一切出它的全部结论:

我刚刚意识到numpy.savetxt ndarrays上的笛卡儿超过2个维度...这可能是通过设计,因为没有内在定义的方式来指示文本文件中的其他维度。

E.g.这(二维数组)工作正常

import numpy as np 
x = np.arange(20).reshape((4,5)) 
np.savetxt('test.txt', x) 

而同样的事情会失败(一个相当不提供信息的错误:TypeError: float argument required, not numpy.ndarray)的三维阵列:

import numpy as np 
x = np.arange(200).reshape((4,5,10)) 
np.savetxt('test.txt', x) 

一个解决办法就是打破3D (或更大)阵列分成2D切片。例如。

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) 

然而,我们的目标是清晰可读,同时仍然容易读回与numpy.loadtxt。因此,我们可以稍微详细一点,并使用注释掉的线区分切片。默认情况下,numpy.loadtxt将忽略任何以#开头的行(或任何由comments kwarg指定的字符)。 (这看起来更详细的比它实际上是...)

import numpy as np 

# Generate some test data 
data = np.arange(200).reshape((4,5,10)) 

# Write the array to disk 
with file('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}\n'.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\n') 

这产生了:

# 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 

回读的是很容易的,只要我们知道原来阵列的形状。我们可以做numpy.loadtxt('test.txt').reshape((4,5,10))。作为一个例子(你可以在同一行做到这一点,我只是详细的澄清事情):

# 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) 
+2

+1,另请参阅'numpy.loadtxt'(http://docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt。 html) – 2010-09-10 14:22:27

+0

好吧,它的文本也很有用,如果你可以用一个简单的代码示例来格式化你的答案,我会接受你的答案:-) – 2010-09-10 14:22:47

+0

我必须赶上公车,但我会添加一个代码示例,只要我进入...谢谢! – 2010-09-10 14:26:14

22

我不确定这是否符合您的要求,因为我认为您有兴趣让人们可以读取文件,但如果这不是主要问题,只需pickle它。

要保存它:

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(data1, output) 
output.close() 

读回:

import pprint, pickle 

pkl_file = open('data.pkl', 'rb') 

data1 = pickle.load(pkl_file) 
pprint.pprint(data1) 

pkl_file.close() 
+0

@ badbod99 - 因为Joe Kington的回答比我的好:) – 2010-09-10 14:25:58

1

你可以简单地穿越在三个嵌套循环的阵列和写它们的值到您的文件。阅读时,只需使用相同的精确回路结构。您将按照正确的顺序获取值,以再次正确填充阵列。

7

如果你不” t需要一个人类可读的输出,另一个选项你不能ry将数组保存为一个MATLAB .mat文件,该文件是一个结构化数组。我鄙视MATLAB,但我可以在极少数行中读写.mat这一事实很方便。

与乔金顿的回答,这样做的好处是,你不需要知道在.mat文件中的数据的原始形状,即无需通过阅读来重塑。而且,不像使用pickle,一个.mat文件可以通过MATLAB读取,也可以读取一些其他程序/语言。

下面是一个例子:

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']) 

如果您忘记了阵列正在.mat文件命名为关键,你总是可以做:

print matdata.keys() 

当然,你可以存储很多使用更多键的数组。

所以是的 - 它不会被你的眼睛阅读,但只需要2行来写和读数据,我认为这是一个公平的权衡。

看看该文档为scipy.io.savematscipy.io.loadmat 也是本教程页面:scipy.io File IO Tutorial

7

ndarray.tofile()也应该努力

例如如果您的阵列被称为a

a.tofile('yourfile.txt',sep=" ",format="%s") 

不知道如何获得换行格式。

编辑(信用凯文J.黑色的评论here):

Since version 1.5.0, np.tofile() takes an optional parameter newline='\n' to allow multi-line output. https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.savetxt.html

+0

但是有没有办法从texfile创建原始数组? – 2018-02-23 16:44:28

+0

@AhashanAlamSojib请参阅https://stackoverflow.com/questions/3518778/how-to-read-csv-into-record-array-in-numpy – atomh33ls 2018-02-23 16:49:21

0

我有办法用一个简单的filename.write()操作来做到这一点。它对我来说工作正常,但我正在处理具有〜1500数据元素的数组。

我基本上只是有循环迭代通过该文件,并将其写入到输出目的地逐行在csv样式输出。

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("\n") 

if和elif语句用于在数据元素之间添加逗号。无论出于何种原因,当以nd数组的形式读取文件时,这些都会被剥离。我的目标是将该文件输出为csv,因此该方法有助于处理该文件。

希望这会有所帮助!

相关问题