2010-09-10 16 views
79

In einer anderen Frage boten andere Benutzer Hilfe an, wenn ich das Array liefern konnte, mit dem ich Probleme hatte. Jedoch scheiterte ich sogar bei einer grundlegenden E/A-Aufgabe, wie das Schreiben eines Arrays in eine Datei.Wie schreibe ich ein mehrdimensionales Array in eine Textdatei?

Kann jemand erklären, welche Art von Schleife ich ein 4x11x14 numpy Array zu Datei schreiben müsste?

Dieses Array besteht aus vier 11 x 14 Arrays, also sollte ich es mit einer netten Newline formatieren, um anderen das Lesen der Datei zu erleichtern.

Bearbeiten: Also habe ich die Funktion numpy.savetxt versucht. Seltsamerweise gibt es die folgenden Fehler:

TypeError: float argument required, not numpy.ndarray 

Ich gehe davon aus, dass dies, weil die Funktion nicht mit mehrdimensionalen Arrays funktioniert? Irgendwelche Lösungen, wie ich sie in einer Datei haben möchte?

+0

Entschuldigung, lesen Sie erneut Ihre Frage nach dem Posten meiner Antwort, und vermuten, dass es nicht Ihren Bedürfnissen entspricht - wenn nicht, ping mich zurück und ich werde eine Alternative posten. (Schön, dich in diesem Teil der Ex-Quadrilogie zu sehen!) –

+0

Eigentlich - sieht so aus, als würde Joe Kingtons Antwort für dich funktionieren. –

Antwort

149

Wenn Sie es auf die Festplatte schreiben möchten, so dass es leicht als ein numpliges Array zurückzulesen ist, schauen Sie in numpy.save. Das Beizen funktioniert auch gut, aber es ist weniger effizient für große Arrays (was bei Ihnen nicht der Fall ist, also ist beides völlig in Ordnung).

Wenn Sie möchten, dass es für Menschen lesbar ist, schauen Sie in numpy.savetxt.

Edit: Also, es wie savetxt scheint eine Option für Arrays mit> 2 Dimensionen ... Aber gerade zu ziehen alles, um es voll Schluss nicht ganz so groß ist:

Ich habe erkannt, dass numpy.savetxt Drosseln auf ndarrays mit mehr als 2 Dimensionen ... Dies ist wahrscheinlich von Entwurf, da es keine inhärent definierte Möglichkeit gibt, zusätzliche Dimensionen in einer Textdatei anzugeben.

z. Dieses (a Array 2D) arbeitet

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

fein Während die gleiche Sache scheitern würde (mit einem eher uninformativ Fehler: TypeError: float argument required, not numpy.ndarray) für ein 3D-Array:

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

Eine Abhilfe ist nur das 3D zu brechen (oder größer) Array in 2D-Slices. Z.B.

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) 

aber unser Ziel ist es klar für Menschen lesbare, zu sein, während immer noch leicht wieder mit numpy.loadtxt lesen ist. Daher können wir etwas ausführlicher sein und die Segmente unter Verwendung von auskommentierten Zeilen unterscheiden. Standardmäßig ignoriert numpy.loadtxt alle Zeilen, die mit # beginnen (oder welches Zeichen auch immer von comments kwarg angegeben wird). (Das sieht ausführlicher als es tatsächlich ist ...)

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

Dies ergibt:

# 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 

es zurück in Reading ist sehr einfach, solange wir die Form des ursprünglichen Arrays kennen. Wir können einfach numpy.loadtxt('test.txt').reshape((4,5,10)) tun. Als Beispiel (Sie können diese Linie in einer tun, ich meine es ausführlich nur Dinge zu klären):

# 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 von mir, siehe auch 'numpy.loadtxt' (http://docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt. html) –

+0

Gut lesbar als Text ist auch sehr nützlich, wenn Sie Ihre Antwort mit einem kleinen Code-Beispiel formatieren können, werde ich Ihre Antwort akzeptieren :-) –

+0

Ich muss den Bus fangen, aber ich werde hinzufügen ein Code-Beispiel, sobald ich reinkomme ... Danke! –

22

Ich bin mir nicht sicher, ob dies Ihren Anforderungen entspricht, da ich denke, dass Sie daran interessiert sind, die Datei lesbar zu machen, aber wenn das kein primäres Anliegen ist, einfach pickle.

es zu speichern:

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() 

es wieder zu lesen:

import pprint, pickle 

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

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

pkl_file.close() 
+0

@ badbod99 - weil Joe Kingtons Antwort besser ist als meine :) –

1

Sie können einfach das Array in drei verschachtelten Schleifen durchlaufen und ihre Werte zu Ihrer Datei schreiben. Zum Lesen verwenden Sie einfach die gleiche exakte Schleifenkonstruktion. Sie erhalten die Werte in genau der richtigen Reihenfolge, um Ihre Arrays wieder korrekt zu füllen.

7

Wenn Sie don‘ t brauchen eine menschenlesbare Ausgabe, eine andere Option, die Sie nicht könnten ry ist das Array als MATLAB .mat Datei zu speichern, die ein strukturiertes Array ist. Ich verachte MATLAB, aber die Tatsache, dass ich ein .mat in sehr wenigen Zeilen sowohl lesen als auch schreiben kann, ist praktisch.

Im Gegensatz zu Joe Kington Antwort ist der Vorteil davon, dass Sie sich beim Lesen neu zu gestalten brauchen nicht in der .mat Datei, dh keine Notwendigkeit, die ursprüngliche Form der Daten zu kennen. Und im Gegensatz zu pickle verwenden, Eine .mat Datei kann von MATLAB und wahrscheinlich auch von anderen Programmen/Sprachen gelesen werden. Hier

ein Beispiel:

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

Wenn Sie den Schlüssel vergessen, dass das Array in der .mat Datei mit dem Namen ist, können Sie immer tun:

print matdata.keys() 

Und natürlich können Sie viele speichern Arrays, die viel mehr Schlüssel verwenden.

Also ja - es wird nicht mit Ihren Augen lesbar sein, aber dauert nur zwei Zeilen, um die Daten zu schreiben und zu lesen, was meiner Meinung nach einen fairen Kompromiss darstellt.

Werfen Sie einen Blick auf die Dokumentation für scipy.io.savemat und scipy.io.loadmat und auch dieses Tutorial Seite: scipy.io File IO Tutorial

7

ndarray.tofile() sollte auch

arbeiten z.B.wenn Ihr Array wird a genannt:

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

Nicht sicher, wie wenn Newline Formatierung zu erhalten.

bearbeiten (Kredit Kevin J. Black Kommentar 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

Aber gibt es eine Möglichkeit, Original-Array aus der Texdatei zu erstellen? –

+0

@AhashanAlamSojib siehe https://stackoverflow.com/questions/3518778/how-to-read-csv-into-record-array-in-numpy – atomh33ls

0

Ich habe einen Weg, es zu tun, um einen einfach filename.write() Betrieb mit. Es funktioniert gut für mich, aber ich habe es mit Arrays mit ~ 1500 Datenelementen zu tun.

Ich habe im Grunde nur For-Schleifen durch die Datei durchlaufen und schreiben Sie es in einer Ausgabe CSV-Stil Zeile für Zeile an das Ausgabeziel.

Die Anweisungen if und elif werden verwendet, um Kommata zwischen den Datenelementen hinzuzufügen. Aus irgendeinem Grund werden diese beim Lesen der Datei als nd-Array entfernt. Mein Ziel war es, die Datei als csv auszugeben, also hilft diese Methode, damit umzugehen.

Hoffe, das hilft!

Verwandte Themen