76

我想将同一个数组的 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
4

9 回答 9

86

这似乎做你想做的事:

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 解决方案也很快。

于 2010-04-08T09:38:22.977 回答
51

当然还有比较明显的:

Data[...,0] + 1j * Data[...,1]
于 2012-09-05T19:34:07.863 回答
28

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

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]

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

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

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

于 2014-02-24T18:51:09.783 回答
18

这就是您正在寻找的:

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])
于 2014-01-06T17:09:09.373 回答
15

我是 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)
于 2013-10-28T18:48:12.443 回答
4
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)
于 2017-03-12T06:47:56.560 回答
0

如果你真的想勉强提高性能(使用大阵列),可以使用numexpr ,它利用了多个内核。

设置:

>>> import numpy as np
>>> Data = np.random.randn(64, 64, 64, 2)
>>> x, y = Data[...,0], Data[...,1]

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)

与快速 numpy 方法相比:

>>> %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)
于 2018-08-15T12:45:30.953 回答
0

我使用以下方法:

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
于 2020-09-02T13:34:24.163 回答
-1

这对我有用:

输入:

[complex(a,b) for a,b in zip([1,2,3],[1,2,3])]

输出:

[(1+4j), (2+5j), (3+6j)]
于 2011-07-18T19:08:27.107 回答