Wie schreibe ich ein mehrdimensionales Array in eine Textdatei?

Lesezeit: 8 Minuten

Wie schreibe ich ein mehrdimensionales Array in eine
Ivo Flipse

In einer anderen Frage boten andere Benutzer Hilfe an, wenn ich das Array liefern könnte, mit dem ich Probleme hatte. Allerdings scheitere ich sogar bei einer grundlegenden E/A-Aufgabe, wie dem Schreiben eines Arrays in eine Datei.

Kann jemand erklären, welche Art von Schleife ich benötigen würde, um ein 4x11x14-numpy-Array in eine Datei zu schreiben?

Dieses Array besteht aus vier 11 x 14 Arrays, also sollte ich es mit einem netten Zeilenumbruch formatieren, um das Lesen der Datei für andere zu erleichtern.

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

TypeError: float argument required, not numpy.ndarray

Ich nehme an, dass dies daran liegt, dass die Funktion nicht mit mehrdimensionalen Arrays funktioniert? Irgendwelche Lösungen, wie ich sie in einer Datei haben möchte?

1647537368 864 Wie schreibe ich ein mehrdimensionales Array in eine
Joe Kington

Wenn Sie es auf die Festplatte schreiben möchten, damit es einfach als numpy-Array wieder eingelesen werden kann, sehen Sie sich das an numpy.save. Das Beizen funktioniert auch gut, ist aber für große Arrays weniger effizient (was bei Ihnen nicht der Fall ist, also ist beides vollkommen in Ordnung).

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

Bearbeiten: Es scheint also so savetxt ist keine so gute Option für Arrays mit> 2 Dimensionen … Aber nur um alles zu Ende zu bringen:

Das ist mir gerade klar geworden numpy.savetxt verschluckt sich bei Ndarrays mit mehr als 2 Dimensionen … Dies ist wahrscheinlich beabsichtigt, da es keine inhärent definierte Möglichkeit gibt, zusätzliche Dimensionen in einer Textdatei anzugeben.

ZB Dies (ein 2D-Array) funktioniert gut

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

Während dasselbe fehlschlagen würde (mit einem eher uninformativen 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 Problemumgehung besteht darin, das 3D-Array (oder größer) einfach in 2D-Slices aufzuteilen. Z.B

x = np.arange(200).reshape((4,5,10))
with open('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 leicht wieder eingelesen werden zu können numpy.loadtxt. Daher können wir etwas ausführlicher sein und die Slices mit auskommentierten Zeilen unterscheiden. Standardmäßig, numpy.loadtxt ignoriert alle Zeilen, die mit beginnen # (oder welches Zeichen auch immer von der angegeben wird comments Kwar). (Das sieht 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

Das Wiedereinlesen ist sehr einfach, solange wir die Form des ursprünglichen Arrays kennen. Wir können einfach tun numpy.loadtxt('test.txt').reshape((4,5,10)). Als Beispiel (Sie können dies in einer Zeile tun, ich bin nur ausführlich, um die Dinge zu verdeutlichen):

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

    – Dominic Rodger

    10. September 2010 um 14:22 Uhr

  • Es gibt jetzt eine viel einfachere Lösung für dieses Problem hier: yourStrArray = np.array([str(val) for val in yourMulDArray],dtype=’string’); np.savetxt(‘IhreTextdatei.txt’,IhrStrArray,fmt=’%s’)

    – Greg Kramida

    13. Dezember 2012 um 15:26 Uhr

  • @GregKramida und wie stellen Sie das Array wieder her?

    – astrojuanlu

    11. April 2013 um 13:01 Uhr

  • @Juanlu001: Ich weiß, dass numpy.loadtxt(…) auch ein dtype-Argument akzeptiert, das auf np.string_ gesetzt werden kann. Das würde ich erstmal versuchen. Es gibt auch ein numpy.fromstring(…) zum Parsen von Arrays aus Strings.

    – Greg Kramida

    11. April 2013 um 16:31 Uhr


  • Hey, was ist, wenn ich ein Bildarray speichern muss? Wie würden wir die Größe ändern, wenn die Bildgröße beispielsweise 512 x 512 beträgt?

    – Ambika Saxena

    30. August 2017 um 13:46 Uhr

1647537369 148 Wie schreibe ich ein mehrdimensionales Array in eine
Dominik Rodger

Ich bin mir nicht sicher, ob dies Ihren Anforderungen entspricht, da Sie meiner Meinung nach daran interessiert sind, die Datei für Menschen lesbar zu machen, aber wenn dies kein Hauptanliegen ist, nur pickle es.

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 nachzulesen:

import pprint, pickle

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

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

pkl_file.close()

  • Sie brauchen es vielleicht nicht pprint um das Wörterbuch auszudrucken.

    – zy

    28. Januar 2019 um 22:29 Uhr


Wenn Sie keine für Menschen lesbare Ausgabe benötigen, können Sie das Array auch als MATLAB-Datei speichern .mat Datei, die ein strukturiertes Array ist. Ich verachte MATLAB, aber die Tatsache, dass ich sowohl lesen als auch schreiben kann .mat in sehr wenigen Zeilen ist bequem.

Im Gegensatz zu Joe Kingtons Antwort besteht der Vorteil darin, dass Sie müssen die ursprüngliche Form der Daten nicht kennen in dem .mat Datei, dh beim Einlesen entfällt das Umformen. Und im Gegensatz zur Verwendung pickleein .mat Datei kann von MATLAB und wahrscheinlich auch von einigen anderen Programmen/Sprachen gelesen werden.

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, mit dem das Array in der benannt ist .mat Datei können Sie jederzeit Folgendes tun:

print matdata.keys()

Und natürlich können Sie viele Arrays mit viel mehr Schlüsseln speichern.

Also ja – es wird mit Ihren Augen nicht lesbar sein, aber es dauert nur 2 Zeilen, um die Daten zu schreiben und zu lesen, was meiner Meinung nach ein fairer Kompromiss ist.

Werfen Sie einen Blick in die Dokumentation für scipy.io.savemat
und scipy.io.loadmat
und auch diese Tutorial-Seite: scipy.io-Datei-IO-Tutorial

Wie schreibe ich ein mehrdimensionales Array in eine
atomh33ls

ndarray.tofile() sollte auch funktionieren

zB wenn Ihr Array aufgerufen wird a:

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

Ich bin mir jedoch nicht sicher, wie ich die Zeilenumbruchformatierung erhalten soll.

Bearbeiten (Gutschrift von Kevin J. Blacks Kommentar hier):

Seit Version 1.5.0, np.tofile() nimmt einen optionalen Parameter an
newline="\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)

hoffe das hilft

Wie schreibe ich ein mehrdimensionales Array in eine
Shantanu Pathak

Sie können auch mehrdimensionale Array-Daten in NumPy speichern .npy Dateityp (es ist eine Binärdatei).

  1. Verwenden Sie numpy save() Funktion zum Speichern von Daten in einer Datei:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) #shape (3x3)
np.save('filename.npy', a)
  1. Entladen mit numpy load() Funktion:
b = np.load('filename.npy')

Datei-E/A kann oft ein Engpass bei Codes sein. Deshalb ist es wichtig zu wissen, dass ASCII-I/O immer um Größenordnungen langsamer ist als binäre I/O. Ich habe einige der Lösungsvorschläge mit verglichen Perfplot:

Geben Sie hier die Bildbeschreibung ein

Code zum Reproduzieren der Handlung:

import json
import pickle

import numpy as np
import perfplot
import scipy.io


def numpy_save(data):
    np.save("test.dat", data)


def numpy_savetxt(data):
    np.savetxt("test.txt", data)


def numpy_savetxt_fmt(data):
    np.savetxt("test.txt", data, fmt="%-7.2f")


def pickle_dump(data):
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)


def scipy_savemat(data):
    scipy.io.savemat("test.dat", mdict={"out": data})


def numpy_tofile(data):
    data.tofile("test.txt", sep=" ", format="%s")


def json_dump(data):
    with open("test.json", "w") as f:
        json.dump(data.tolist(), f)


perfplot.save(
    "out.png",
    setup=np.random.rand,
    n_range=[2 ** k for k in range(20)],
    kernels=[
        numpy_save,
        numpy_savetxt,
        numpy_savetxt_fmt,
        pickle_dump,
        scipy_savemat,
        numpy_tofile,
        json_dump,
    ],
    equality_check=None,
)

1005100cookie-checkWie schreibe ich ein mehrdimensionales Array in eine Textdatei?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy