2010-09-10 179 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,因此該方法有助於處理該文件。

希望這會有所幫助!

相關問題