2010-04-08 55 views
39

我發誓這應該是那麼容易...爲什麼不是? :(Numpy:從2個真正的數組創建一個複雜的數組?

其實,我想結合2個部分在同一陣列中,使複雜的陣列:

Data[:,:,:,0] , Data[:,:,:,1] 

這些不工作:

x = np.complex(Data[:,:,:,0], Data[:,:,:,1]) 
x = complex(Data[:,:,:,0], Data[:,:,:,1]) 

我缺少的東西? ?難道numpy的不喜歡複雜的數字進行排列的功能這裏的錯誤:

TypeError: only length-1 arrays can be converted to Python scalars 

回答

50

這似乎做你想要什麼:

numpy.apply_along_axis(lambda args: [complex(*args)], 3, Data) 

這裏是另一種解決方案:

# The ellipsis is equivalent here to ":,:,:"... 
numpy.vectorize(complex)(Data[...,0], Data[...,1]) 

而且又簡單的解決辦法:

Data[...,0] + 1j * Data[...,1] 

PS:如果你想節省內存(無中間陣列):

result = 1j*Data[...,1]; result += Data[...,0] 

devS的解決方案也很快。

+0

同樣的錯誤恐怕:類型錯誤:只有長度爲1的陣列可以被轉換到Python標量 – 2010-04-08 09:42:18

+0

@Duncan:我進行試驗後,在原來的答案更新。它現在似乎在工作。 – EOL 2010-04-08 09:43:04

+0

非常感謝,確實有效。雖然它非常慢(正如你所期望的那樣 - 因爲它不是一個真正的numpy函數),現在每個循環需要5秒而不是0.1 – 2010-04-08 09:45:57

0

爲我工作:

輸入:

from scipy import * 

array([[1,2],[3,2]]).astype(complex) 

輸出:

array([[ 1.+0.j, 2.+0.j], 
     [ 3.+0.j, 2.+0.j]]) 
+4

-1,這使虛部等於零 – 2014-01-28 15:05:01

26

有當然,相當明顯的:

Data[...,0] + 1j * Data[...,1] 
+8

另外'Data.view(complex)' – 2012-09-05 21:40:09

7

我是蟒蛇新手,所以這可能不是最有效的方法,但如果我正確理解問題的意圖,下面列出的步驟爲我工作。

>>> 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) 
+0

有趣的想法。然而,問題是關於'Data [:,:,0]'和'Data [:,:,1]'(比你的'a'更復雜)。另外,不要使用'zeros()',而應該使用更快更合適的'empty()'。 – EOL 2014-01-29 22:35:21

+0

我將其與Data [...,0] + 1j * Data [...,1]解決方案進行了比較。使用Data = random.rand(100,100,1000,2),c =零(a.shape [: - 1],dtype = complex); c.real = Data [...,0]; c.imag =數據[...,1];比簡單的Data [...,0] + 1j * Data [...,1]快兩倍。令人驚訝的是,使用空而不是零的效果可以忽略不計。 – 2014-02-06 08:51:15

+1

+1。注意:我用最後一個答案的變體得到相同的速度:'result = 1j * Data [...,1];結果+ =數據[...,0]'。但是,如果不使用單個公式,這個答案更自然。 – EOL 2014-02-07 13:19:13

11

這就是你正在尋找:

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]) 
+0

這只是皮埃爾通用汽車公司或我的早期答案的部分重複:我認爲它的唯一影響是讓人們幾乎沒有附加價值的時間(超出範例),所以我建議您刪除它。 – EOL 2017-02-14 11:55:59

14

如果你的實部和虛部沿最後一維的切片和你的陣列是沿最後一個維度是連續的,你可以做

A.view(dtype=np.complex128) 

如果您使用的是單精度浮點值,這將是

A.view(dtype=np.complex64) 

這裏是一個更全面的例子

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) 

如果你想擺脫從鑄造保持周圍的額外維度的,你可以不喜歡

A_comp = A.view(dtype=np.complex128)[...,0] 

這樣做是因爲,在內存,一個複數實際上只是兩個浮點數。第一個代表實部,第二個代表虛部。 數組的視圖方法更改數組的dtype以反映您想要將相鄰的兩個浮點值視爲單個複數並相應地更新該維。

該方法不會複製數組中的任何值或執行任何新的計算,它只會創建一個新的數組對象,以不同的方式查看同一塊內存。 這使得這個操作可以執行比任何涉及複製值更快。這也意味着複數值陣列中所做的任何更改都會反映在具有實部和虛部的陣列中。

如果刪除在類型轉換後立即出現的額外軸,恢復原始數組也可能有點複雜。 像A_comp[...,np.newaxis].view(np.float64)這樣的東西目前不工作,因爲在撰寫本文時,NumPy在添加新軸時未檢測到該數組仍然是C連續的。 見this issueA_comp.view(np.float64).reshape(A.shape)似乎在大多數情況下工作。

+0

+1:非常清楚地解釋該方法的侷限性。您可能需要明確添加另一個限制(「A_comp」和「A」之間的共享內存),以及此方法的優點(速度)。 – EOL 2014-04-13 04:14:39

+0

@EOL謝謝。我已經相應地更新了答案。 – IanH 2014-04-20 03:46:39

2
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) 
相關問題