2017-02-20 6 views
2

Ich weiß, dass, wenn ich Arrays mit komplexen Zahlen mit numpy speichern und laden möchte, kann ich die Methode verwenden, die hier beschrieben wird: How to save and load an array of complex numbers using numpy.savetxt?. jedochLaden komplexer Zahlen mit numpy.loadtxt

Angenommen, dass jemand nicht darüber wußte und rettete ihre Array numbers mit numpy.savetxt("numbers.txt",numbers), eine Datei mit Einträgen der Form Herstellung

(0.000000000000000000e+00+-2.691033635430225765e-02j) . 

In diesem Fall

numbers_load = numpy.loadtxt("numbers.txt").view(complex) 

wird, vorhersagbar, scheitern im Sinne von

ValueError: could not convert string to float: (0.000000000000000000e+00+-2.691033635430225765e-02j) . 

Was wo Kann eine einfache Methode sein, die komplexen Zahlen aus dieser Datei zu extrahieren (ohne eine andere Version zu erzeugen)?

Antwort

0

Bevor das Array speichern, sollten Sie .view(float) verwenden, um ein Array von float s zu konvertieren, und dann .view(complex) die float s zurück zu complex Zahlen auf Laden zu konvertieren.

In [1]: import numpy as np 

In [2]: A = np.array([1+2j, 2+5j, 3-4j, -3+1j]) 

In [3]: A.view(float) 
Out[3]: array([ 1., 2., 2., 5., 3., -4., -3., 1.]) 

In [4]: np.savetxt("numbers.txt", A.view(float)) 

In [5]: np.loadtxt("numbers.txt") 
Out[5]: array([ 1., 2., 2., 5., 3., -4., -3., 1.]) 

In [6]: np.loadtxt("numbers.txt").view(complex) 
Out[6]: array([ 1.+2.j, 2.+5.j, 3.-4.j, -3.+1.j]) 
1

Wenn Sie die Datei nicht ändern können, können Sie die Saiten verwandeln, wie Sie sie in Zeile für Zeile lesen.

import numpy as np 
import re 

# a regular expression that picks out the two components of the complex number 
reg = re.compile('(-?\d.\d*e[+-]\d\d)\+(-?\d.\d*e[+-]\d\d)') 
# a function that returns a properly formatted string 
edit = lambda s: reg.search(s).expand(r'\1 \2') 

with open("numbers.txt", 'r') as fobj: 
    # calling map applies the edit function to each line of numbers.txt in turn 
    numbers_load = np.loadtxt(map(edit, fobj)) 
print(numbers_load) # [ 0.   -0.02691034] 
print(numbers_load.view('complex')) # [ 0.-0.02691034j] 
0

Die Dokumentation für savetxt über fmt Optionen für eine komplexe Anordnung zu sprechen.

Beginnend mit einem 1D-Array:

In [17]: np.arange(5)+np.arange(5,0,-1)*1j 
Out[17]: array([ 0.+5.j, 1.+4.j, 2.+3.j, 3.+2.j, 4.+1.j]) 
In [18]: arr = np.arange(5)+np.arange(5,0,-1)*1j 

Der Standard die Zahlen zu schreiben ist, eine () Zeichenfolge pro Zeile. Das mit loadtxt (oder genfromtxt) zu lesen wird ein Problem sein. Es muss als String geladen und dann zeilenweise konvertiert werden.

Es heißt, ich kann ein Format für die realen und imaginären Teile angeben, in diesem Fall speichert es als 2 Spalten. Das ist einfach zu lesen mit loadtxt.

In [21]: np.savetxt('test.txt',arr, fmt='%f %f') 
In [22]: cat test.txt 
0.000000 5.000000 
1.000000 4.000000 
2.000000 3.000000 
3.000000 2.000000 
4.000000 1.000000 

In [23]: np.loadtxt('test.txt') 
Out[23]: 
array([[ 0., 5.], 
     [ 1., 4.], 
     [ 2., 3.], 
     [ 3., 2.], 
     [ 4., 1.]]) 

In [25]: np.loadtxt('test.txt').view(complex) 
Out[25]: 
array([[ 0.+5.j], 
     [ 1.+4.j], 
     [ 2.+3.j], 
     [ 3.+2.j], 
     [ 4.+1.j]]) 

mit einem 2D-Komplex Array Ich brauche fmt für alle Spalten angeben

In [28]: arr1=np.array((arr, arr*.1, arr+1)) 
In [29]: arr1 
Out[29]: 
array([[ 0.0+5.j , 1.0+4.j , 2.0+3.j , 3.0+2.j , 4.0+1.j ], 
     [ 0.0+0.5j, 0.1+0.4j, 0.2+0.3j, 0.3+0.2j, 0.4+0.1j], 
     [ 1.0+5.j , 2.0+4.j , 3.0+3.j , 4.0+2.j , 5.0+1.j ]]) 

In [33]: np.savetxt('test.txt',arr1, fmt=['%f %f']*5) 
In [34]: cat test.txt 
0.000000 5.000000 1.000000 4.000000 2.000000 3.000000 3.000000 2.000000 4.000000 1.000000 
0.000000 0.500000 0.100000 0.400000 0.200000 0.300000 0.300000 0.200000 0.400000 0.100000 
1.000000 5.000000 2.000000 4.000000 3.000000 3.000000 4.000000 2.000000 5.000000 1.000000 
In [35]: np.loadtxt('test.txt').view(complex) 
Out[35]: 
array([[ 0.0+5.j , 1.0+4.j , 2.0+3.j , 3.0+2.j , 4.0+1.j ], 
     [ 0.0+0.5j, 0.1+0.4j, 0.2+0.3j, 0.3+0.2j, 0.4+0.1j], 
     [ 1.0+5.j , 2.0+4.j , 3.0+3.j , 4.0+2.j , 5.0+1.j ]]) 

Die docs mit allen Spalten einen langen Format-String zeigen, aber offenbar eine Liste von Strings arbeitet

In [36]: ['%f %f']*5 
Out[36]: ['%f %f', '%f %f', '%f %f', '%f %f', '%f %f'] 

savetxt verbindet diese Liste mit dem Trennzeichen, um eine lange Formatzeichenfolge zu erstellen.

In [37]: np.savetxt('test.txt',arr1, fmt=['%f %f']*5, delimiter=',') 
In [38]: cat test.txt 
0.000000 5.000000,1.000000 4.000000,2.000000 3.000000,3.000000 2.000000,4.000000 1.000000 
... 

Für loadtxt das Trennzeichen zwischen komplexen Teilen und Spalten kompatibel sein:

In [39]: np.savetxt('test.txt',arr1, fmt=['%f %f']*5, delimiter=' ') 
In [40]: cat test.txt 
0.000000 5.000000 1.000000 4.000000 2.000000 3.000000 3.000000 2.000000 4.000000 1.000000 
... 

In Summe, die Speichern/Laden Rundfahrt am einfachsten ist, wenn die save mit Last-kompatible Formate erfolgt.

1

Sie könnten converters verwenden, um das benutzerdefinierte Format zu verarbeiten. Das einzige Problem, das das korrekte Lesen des komplexen Wertes verhindert, ist die +- in 1+-2j, ersetzt sie zu 1-2j würde funktionieren.

>>> numpy.savetxt('1.txt', numpy.array([2.3+4.5j, 6.7-0.89j])) 

>>> numpy.loadtxt('1.txt', dtype=complex) # <- doesn't work directly 
ValueError: complex() arg is a malformed string 

>>> numpy.loadtxt('1.txt', dtype=complex, converters={0: lambda s: complex(s.decode().replace('+-', '-'))}) 
array([ 2.3+4.5j , 6.7-0.89j]) 
Verwandte Themen