In einer anderen Frage boten andere Benutzer etwas Hilfe an, wenn ich das Array bereitstellen könnte, mit dem ich Probleme hatte. Ich scheitere jedoch sogar an einer grundlegenden E/A-Aufgabe, z. B. beim Schreiben eines Arrays in eine Datei.
Kann jemand erklären, welche Art von Schleife ich für ein 4x11x14-Numpy-Array in eine Datei schreiben müsste?
Dieses Array besteht aus vier 11 x 14-Arrays, daher sollte ich es mit einem Nice-Zeilenumbruch formatieren, um anderen das Lesen der Datei zu erleichtern.
Edit : Also habe ich die numpy.savetxt-Funktion ausprobiert. Seltsamerweise gibt es den folgenden Fehler:
TypeError: float argument required, not numpy.ndarray
Ich gehe davon aus, dass dies daran liegt, dass die Funktion mit mehrdimensionalen Arrays nicht funktioniert. Irgendwelche Lösungen, wie ich sie in einer Datei haben möchte?
Wenn Sie es auf die Festplatte schreiben möchten, um es als Numpy-Array wieder einzulesen, schauen Sie in numpy.save
. Das Beizen funktioniert ebenfalls gut, ist jedoch bei großen Arrays weniger effizient (was bei Ihnen nicht der Fall ist, und ist auch vollkommen in Ordnung).
Wenn Sie möchten, dass es für Menschen lesbar ist, schauen Sie in numpy.savetxt
.
Edit: Es sieht also so aus, als wäre savetxt
für Arrays mit> 2 Dimensionen nicht ganz so gut geeignet ... Aber um alles auf den Punkt zu bringen:
Ich habe gerade erkannt, dass numpy.savetxt
auf ndarrays mit mehr als 2 Dimensionen erstickt ... Dies ist wahrscheinlich beabsichtigt, da es keine inhärent definierte Möglichkeit gibt, zusätzliche Dimensionen in einer Textdatei anzugeben.
Z.B. Dieses (ein 2D-Array) funktioniert gut
import numpy as np
x = np.arange(20).reshape((4,5))
np.savetxt('test.txt', x)
Dasselbe würde für ein 3D-Array fehlschlagen (mit einem nicht informativen Fehler: TypeError: float argument required, not numpy.ndarray
):
import numpy as np
x = np.arange(200).reshape((4,5,10))
np.savetxt('test.txt', x)
Eine Problemumgehung besteht darin, das 3D-Array (oder ein höheres Array) in 2D-Schnitte aufzuteilen. 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)
Unser Ziel ist es jedoch, klar lesbar zu sein und dennoch mit numpy.loadtxt
leicht lesbar zu sein. Daher können wir etwas ausführlicher sein und die Slices anhand von auskommentierten Zeilen unterscheiden. Standardmäßig ignoriert numpy.loadtxt
alle Zeilen, die mit #
beginnen (oder welches Zeichen von comments
kwarg angegeben wird). (Das sieht viel ausführlicher aus, 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 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}\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 ist sehr leicht, es wieder einzulesen, solange wir die Form des ursprünglichen Arrays kennen. Wir können einfach numpy.loadtxt('test.txt').reshape((4,5,10))
machen. Als Beispiel (Sie können dies in einer Zeile tun, ich bin nur wortreich, um 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)
Ich bin nicht sicher, ob dies Ihren Anforderungen entspricht, da ich glaube, dass Sie daran interessiert sind, die Datei für Menschen lesbar zu machen, aber wenn dies nicht ein Hauptanliegen ist, nur pickle
it.
Um 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(my_data, output)
output.close()
Um es zurückzulesen:
import pprint, pickle
pkl_file = open('data.pkl', 'rb')
data1 = pickle.load(pkl_file)
pprint.pprint(data1)
pkl_file.close()
Wenn Sie keine vom Menschen lesbare Ausgabe benötigen, können Sie das Array auch als MATLAB .mat
-Datei speichern, bei der es sich um ein strukturiertes Array handelt. Ich hasse MATLAB, aber die Tatsache, dass ich einen .mat
in sehr wenigen Zeilen sowohl lesen als auch schreiben kann, ist praktisch.
Im Gegensatz zur Antwort von Joe Kington besteht der Vorteil darin, dass Sie Sie müssen die ursprüngliche Form der Daten nicht kennen in der .mat
-Datei, dh, Sie müssen sich beim Einlesen nicht umformen. Und anders als bei pickle
Eine .mat
-Datei kann von MATLAB gelesen werden, möglicherweise auch einige andere Programme/Sprachen.
Hier ist 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, den das Array in der Datei .mat
benannt hat, können Sie immer Folgendes tun:
print matdata.keys()
Natürlich können Sie viele Arrays mit vielen weiteren Schlüsseln speichern.
Also ja - es ist mit Ihren Augen nicht lesbar, aber es dauert nur 2 Zeilen, um die Daten zu schreiben und zu lesen, was meiner Meinung nach ein fairer Kompromiss ist.
Sehen Sie sich die Dokumentation für scipy.io.savemat Und scipy.io.loadmat Sowie diese Tutorial-Seite an: scipy.io File IO Tutorial
ndarray.tofile()
sollte auch funktionieren
z.B. wenn Ihr Array a
heißt:
a.tofile('yourfile.txt',sep=" ",format="%s")
Sie sind sich jedoch nicht sicher, wie Sie die Formatierung der Zeilen erreichen können.
Edit (Anrede von Kevin J. Black hier ):
Seit Version 1.5.0 übernimmt
np.tofile()
einen optionalen Parameternewline='\n'
, um eine mehrzeilige Ausgabe zu ermöglichen . https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.savetxt.html
Dafür gibt es spezielle Bibliotheken. (Plus Wrapper für Python)
netCDF4 Python-Schnittstelle: http://www.unidata.ucar.edu/software/netcdf/software.html#Python
hoffe das hilft
Sie können das Array einfach in drei verschachtelten Schleifen durchlaufen und deren Werte in Ihre Datei schreiben. Zum Lesen verwenden Sie einfach dieselbe exakte Schleifenkonstruktion. Sie erhalten die Werte genau in der richtigen Reihenfolge, um Ihre Arrays wieder korrekt zu füllen.
Pickle ist am besten für diese Fälle. Angenommen, Sie haben ein ndarray namens x_train
. Sie können es in eine Datei sichern und mit dem folgenden Befehl wiederherstellen:
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)
Ich habe eine Möglichkeit, dies mit einer einfachen dateiname.write () - Operation zu tun. Es funktioniert gut für mich, aber ich habe es mit Arrays zu tun, die ~ 1500 Datenelemente haben.
Ich habe im Grunde nur für Schleifen, um die Datei zu durchlaufen und sie zeilenweise in einer Ausgabe im CSV-Stil an das Ausgabeziel zu schreiben.
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")
Die if- und Elif-Anweisung werden zum Hinzufügen von Kommas zwischen den Datenelementen verwendet. Aus welchem Grund auch immer, werden diese beim Lesen der Datei als ein Array gelöscht. Mein Ziel war es, die Datei als csv auszugeben, daher hilft diese Methode, damit umzugehen.
Hoffe das hilft!