Ich möchte 2 Teile desselben Arrays zu einem komplexen Array kombinieren:
Data[:,:,:,0] , Data[:,:,:,1]
Diese funktionieren nicht:
x = np.complex(Data[:,:,:,0], Data[:,:,:,1])
x = complex(Data[:,:,:,0], Data[:,:,:,1])
Vermisse ich etwas Mag numpy es nicht, Array-Funktionen für komplexe Zahlen auszuführen? Hier ist der Fehler:
TypeError: only length-1 arrays can be converted to Python scalars
python
arrays
numpy
complex-numbers
Duncan Tait
quelle
quelle
Es gibt natürlich das ziemlich Offensichtliche:
Data[...,0] + 1j * Data[...,1]
quelle
Wenn Ihre Real- und Imaginärteile die Slices entlang der letzten Dimension sind und Ihr Array entlang der letzten Dimension zusammenhängend ist, können Sie dies einfach tun
Wenn Sie Floats mit einfacher Genauigkeit verwenden, ist dies der Fall
Hier ist ein ausführlicheres Beispiel
import numpy as np from numpy.random import rand # Randomly choose real and imaginary parts. # Treat last axis as the real and imaginary parts. A = rand(100, 2) # Cast the array as a complex array # Note that this will now be a 100x1 array A_comp = A.view(dtype=np.complex128) # To get the original array A back from the complex version A = A.view(dtype=np.float64)
Wenn Sie die zusätzliche Dimension entfernen möchten, die vom Casting übrig bleibt, können Sie so etwas tun
A_comp = A.view(dtype=np.complex128)[...,0]
Dies funktioniert, weil eine komplexe Zahl im Speicher eigentlich nur zwei Gleitkommazahlen sind. Der erste repräsentiert den Realteil und der zweite repräsentiert den Imaginärteil. Die Ansichtsmethode des Arrays ändert den d-Typ des Arrays, um anzuzeigen, dass Sie zwei benachbarte Gleitkommawerte als eine einzige komplexe Zahl behandeln möchten, und aktualisiert die Dimension entsprechend.
Diese Methode kopiert keine Werte in das Array und führt keine neuen Berechnungen durch. Sie erstellt lediglich ein neues Array-Objekt, das denselben Speicherblock unterschiedlich anzeigt. Das macht es so, dass diese Operation viel ausgeführt werden kann schneller ausgeführt werden als alles, was das Kopieren von Werten beinhaltet. Dies bedeutet auch, dass alle Änderungen, die im Array mit komplexen Werten vorgenommen werden, im Array mit den Real- und Imaginärteilen wiedergegeben werden.
Es kann auch etwas schwieriger sein, das ursprüngliche Array wiederherzustellen, wenn Sie die zusätzliche Achse entfernen, die unmittelbar nach der Typumwandlung vorhanden ist. Dinge wie
A_comp[...,np.newaxis].view(np.float64)
funktionieren derzeit nicht, da NumPy zum jetzigen Zeitpunkt nicht erkennt, dass das Array beim Hinzufügen der neuen Achse noch C-zusammenhängend ist. Siehe dieses Problem .A_comp.view(np.float64).reshape(A.shape)
scheint jedoch in den meisten Fällen zu funktionieren.quelle
A_comp
undA
) sowie einen Vorteil dieser Methode (Geschwindigkeit) hinzufügen .Das ist, wonach Sie suchen:
from numpy import array a=array([1,2,3]) b=array([4,5,6]) a + 1j*b ->array([ 1.+4.j, 2.+5.j, 3.+6.j])
quelle
Ich bin Python-Neuling, daher ist dies möglicherweise nicht die effizienteste Methode. Wenn ich die Absicht der Frage richtig verstehe, haben die unten aufgeführten Schritte für mich funktioniert.
>>> import numpy as np >>> Data = np.random.random((100, 100, 1000, 2)) >>> result = np.empty(Data.shape[:-1], dtype=complex) >>> result.real = Data[...,0]; result.imag = Data[...,1] >>> print Data[0,0,0,0], Data[0,0,0,1], result[0,0,0] 0.0782889873474 0.156087854837 (0.0782889873474+0.156087854837j)
quelle
Data[:,:,:,0]
undData[:,:,:,1]
(komplizierter als Ihrea
). Anstatt zu verwendenzeros()
, sollten Sie auch das schnellere und angemessenere verwendenempty()
.result = 1j*Data[...,1]; result += Data[...,0]
. Diese Antwort ist jedoch natürlicher, wenn keine einzige Formel verwendet wird.import numpy as np n = 51 #number of data points # Suppose the real and imaginary parts are created independently real_part = np.random.normal(size=n) imag_part = np.random.normal(size=n) # Create a complex array - the imaginary part will be equal to zero z = np.array(real_part, dtype=complex) # Now define the imaginary part: z.imag = imag_part print(z)
quelle
Wenn Sie wirklich Leistung (mit großen Arrays) erzielen möchten , wählen Sie numexpr kann verwendet werden, das mehrere Kerne nutzt.
Konfiguration:
>>> import numpy as np >>> Data = np.random.randn(64, 64, 64, 2) >>> x, y = Data[...,0], Data[...,1]
Mit
numexpr
:>>> import numexpr as ne >>> %timeit result = ne.evaluate("complex(x, y)") 573 µs ± 21.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Im Vergleich zur schnellen Numpy-Methode:
>>> %timeit result = np.empty(x.shape, dtype=complex); result.real = x; result.imag = y 1.39 ms ± 5.74 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
quelle
Ich benutze die folgende Methode:
import numpy as np real = np.ones((2, 3)) imag = 2*np.ones((2, 3)) complex = np.vectorize(complex)(real, imag) # OR complex = real + 1j*imag
quelle
Das hat bei mir funktioniert:
Eingang:
[complex(a,b) for a,b in zip([1,2,3],[1,2,3])]
Ausgabe:
[(1+4j), (2+5j), (3+6j)]
quelle