【问题标题】:Convert complex NumPy array into (n, 2)-array of real and imaginary parts将复杂的 NumPy 数组转换为 (n, 2) 实部和虚部的数组
【发布时间】:2016-08-11 15:20:14
【问题描述】:

我有一个复数值 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)

成功了,但是转置、vstacking、转换为连续数组可能需要一两步。

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

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    您可以使用column_stack 并将两个一维数组作为列堆叠以形成一个二维数组。

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

    【讨论】:

    • 我刚刚检查了这个 :) 它避免了丑陋的索引!
    【解决方案2】:

    没有一个替代品是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.]])
    

    vstack 将其输入通过atleast_2d(m) 传递,确保每个都是 1 行 2d 数组。 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.]])
    

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

    np.concatenate((u.real[:,None],u.imag[:,None]),axis=1)
    

    全部使用np.concatenate; it 和 np.array 是唯一编译的连接函数。

    另一个技巧是使用view

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

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

    对备选方案的另一个测试是询问当u 为 2d 或更高时会发生什么?

    【讨论】:

    • 可以用同样的方法来保存 N x M 复数数组的复制吗?制作 N x M x 2 的 float64?
    【解决方案3】:

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

    u.view("(2,)float")
    

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

    numpy.column_stack([u.real, u.imag])
    

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

    重现情节的代码:

    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(15)],
    )
    

    【讨论】:

      【解决方案4】:

      你可以使用dstack:

      np.dstack((u.real, u.imag))[0]
      #Out[210]:
      #array([[ 1.,  2.],
      #       [ 2.,  4.],
      #       [ 3.,  6.],
      #       [ 4.,  8.]])
      

      【讨论】:

        猜你喜欢
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多