Numpy:从2个真实阵列创建一个复杂的数组?

Dun*_*ait 55 python arrays numpy complex-numbers

我发誓这应该是那么容易......为什么不呢?:(

实际上,我想组合同一个数组的两个部分来组成一个复杂的数组:

Data[:,:,:,0] , Data[:,:,:,1]
Run Code Online (Sandbox Code Playgroud)

这些不起作用:

x = np.complex(Data[:,:,:,0], Data[:,:,:,1])
x = complex(Data[:,:,:,0], Data[:,:,:,1])
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?numpy不喜欢在复数上执行数组函数吗?这是错误:

TypeError: only length-1 arrays can be converted to Python scalars
Run Code Online (Sandbox Code Playgroud)

Eri*_*got 66

这似乎做你想要的:

numpy.apply_along_axis(lambda args: [complex(*args)], 3, Data)
Run Code Online (Sandbox Code Playgroud)

这是另一个解决方案:

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

还有一个更简单的解决方案:

Data[...,0] + 1j * Data[...,1]
Run Code Online (Sandbox Code Playgroud)

PS:如果你想节省内存(没有中间数组):

result = 1j*Data[...,1]; result += Data[...,0]
Run Code Online (Sandbox Code Playgroud)

下面的开发者解决方案也很快.


Pie*_* GM 37

当然有相当明显的:

Data[...,0] + 1j * Data[...,1]
Run Code Online (Sandbox Code Playgroud)

  • 还有`Data.view(复杂)` (10认同)

Ian*_*anH 20

如果您的实部和虚部是最后一个维度的切片,并且您的数组沿着最后一个维度是连续的,那么您可以做

A.view(dtype=np.complex128)
Run Code Online (Sandbox Code Playgroud)

如果您使用单精度浮子,这将是

A.view(dtype=np.complex64)
Run Code Online (Sandbox Code Playgroud)

这是一个更全面的例子

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)
Run Code Online (Sandbox Code Playgroud)

如果你想摆脱铸造中留下的额外尺寸,你可以做类似的事情

A_comp = A.view(dtype=np.complex128)[...,0]
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为在内存中,复数实际上只是两个浮点数.第一个代表实部,第二个代表虚部.数组的视图方法更改数组的dtype以反映您要将两个相邻浮点值视为单个复数并相应地更新维度.

此方法不会复制数组中的任何值或执行任何新计算,它所做的只是创建一个新的数组对象,以不同方式查看同一块内存.这使得它使这个操作可以进行比任何涉及复制值更快.这也意味着复值数组中的任何更改都将反映在具有实部和虚部的数组中.

如果在类型转换后立即删除那里的额外轴,恢复原始数组也可能有点棘手.类似的东西A_comp[...,np.newaxis].view(np.float64)目前不起作用,因为在撰写本文时,NumPy在添加新轴时没有检测到数组仍然是C连续的.看到这个问题. A_comp.view(np.float64).reshape(A.shape)似乎在大多数情况下都有效.


nad*_*pez 14

这是您正在寻找的:

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])
Run Code Online (Sandbox Code Playgroud)

  • 14人不同意!虽然深度很弱并且不值得打勾,但这个例子让我最快地达到了我所需要的。 (3认同)

小智 9

我是python新手,所以这可能不是最有效的方法,但是,如果我正确理解问题的意图,下面列出的步骤对我有效.

>>> 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)
Run Code Online (Sandbox Code Playgroud)

  • 我将其与 Data[…,0] + 1j * Data[…,1] 解决方案进行了比较。数据 = random.rand(100,100,1000,2),c=zeros(a.shape[:-1],dtype=complex);c.real = Data[...,0]; c.imag = 数据[...,1]; 比简单的 Data[…,0] + 1j * Data[…,1] 快 2 倍。令人惊讶的是,使用空而不是零的效果可以忽略不计。 (2认同)
  • +1。注意:我得到了与上一个答案相同的速度:`result = 1j*Data[...,1]; 结果+=数据[...,0]`。不过,如果不使用单一公式,这个答案会更自然。 (2认同)

小智 6

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)
Run Code Online (Sandbox Code Playgroud)