将复杂的 NumPy 数组转换为 (n, 2)-实部和虚部数组

Nic*_*mer 5 python arrays numpy

我有一个复数值的 NumPy 数组,我想将其转换为一个连续的 NumPy 数组,其中实部和虚部分开。

这个

import numpy

u = numpy.array([
    1.0 + 2.0j,
    2.0 + 4.0j,
    3.0 + 6.0j,
    4.0 + 8.0j
    ])

u2 = numpy.ascontiguousarray(numpy.vstack((u.real, u.imag)).T)
Run Code Online (Sandbox Code Playgroud)

可以解决问题,但是转置、vstacking转换为连续数组可能需要一两步。

是否有本机 NumPy 函数可以为我执行此操作?

Nic*_*mer 12

我使用perfplot比较了建议的解决方案。对于大矢量尺寸,恒定时间视图

u.view("(2,)float")
Run Code Online (Sandbox Code Playgroud)

确实是最快的变体。对于较小的n

numpy.column_stack([u.real, u.imag])
Run Code Online (Sandbox Code Playgroud)

可能是最好的(最干净、最快)的选择。

在此输入图像描述

重现情节的代码:

import numpy
import perfplot


def setup(n):
    return numpy.random.rand(n) + 1j * numpy.random.rand(n)


def column_stack(u):
    return numpy.column_stack([u.real, u.imag])


def dstack(u):
    return numpy.dstack((u.real, u.imag))[0]


def concatenate(u):
    return numpy.concatenate(
        (numpy.array(u.real, ndmin=2).T, numpy.array(u.imag, ndmin=2).T), axis=1
    )


def stack(u):
    return numpy.stack((u.real, u.imag), -1)


def view(u):
    return u.view("(2,)float")


perfplot.save(
    "out.png",
    setup=setup,
    kernels=[column_stack, dstack, concatenate, stack, view],
    n_range=[2 ** k for k in range(22)],
)
Run Code Online (Sandbox Code Playgroud)


Nic*_*eli 7

您可以使用column_stack和堆叠两个一维数组作为列来制作单个二维数组。

In [9]: np.column_stack((u.real,u.imag))
Out[9]: 
array([[ 1.,  2.],
       [ 2.,  4.],
       [ 3.,  6.],
       [ 4.,  8.]])
Run Code Online (Sandbox Code Playgroud)


hpa*_*ulj 5

没有任何替代方案是native或保存在重塑、转置等方面。

例如,在内部column_stack将其输入转换为二维“列”数组。有效地它正在做

In [1171]: np.concatenate((np.array(u.real,ndmin=2).T,np.array(u.imag,ndmin=2).T),axis=1)
Out[1171]: 
array([[ 1.,  2.],
       [ 2.,  4.],
       [ 3.,  6.],
       [ 4.,  8.]])
Run Code Online (Sandbox Code Playgroud)

vstack将其输入传递给atleast_2d(m),确保每个输入都是 1 行二维数组。 np.dstack使用atleast_3d(m).

一个新函数是 np.stack

In [1174]: np.stack((u.real,u.imag),-1)
Out[1174]: 
array([[ 1.,  2.],
       [ 2.,  4.],
       [ 3.,  6.],
       [ 4.,  8.]])
Run Code Online (Sandbox Code Playgroud)

它使用None索引来校正连接的维度;有效地:

np.concatenate((u.real[:,None],u.imag[:,None]),axis=1)
Run Code Online (Sandbox Code Playgroud)

所有最终都使用np.concatenate; 它并且np.array是唯一编译的连接函数。

另一个技巧是使用 view

In [1179]: u.view('(2,)float')
Out[1179]: 
array([[ 1.,  2.],
       [ 2.,  4.],
       [ 3.,  6.],
       [ 4.,  8.]])
Run Code Online (Sandbox Code Playgroud)

复数值保存为 2 个相邻的浮点数。因此,可以将相同的数据缓冲区视为纯浮点数,或者将此视图视为 2d 浮点数数组。与concatenate函数相反,这里没有复制。

对替代方案的另一个测试是问当u2d 或更高时会发生什么?