pythonarraysnumpy

Convert complex NumPy array into (n, 2)-array of real and imaginary parts


I have a complex-valued NumPy array that I'd like to convert into a contiguous NumPy array with real and imaginary parts separate.

This

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)

does the trick, but transposing, vstacking, and converting to a contiguous array is probably a step or two too much.

Is there a native NumPy function that does this for me?


Solution

  • None of the alternatives are native or save on reshape, transposes etc.

    For example internally column_stack converts its inputs to 2d 'column' arrays. Effectively it is doing

    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 passes its inputs through atleast_2d(m), making sure each is a 1 row 2d array. np.dstack uses atleast_3d(m).

    A new function is np.stack

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

    It uses None indexing to correct dimensions for concatenation; effectively:

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

    All end up using np.concatenate; it and np.array are the only compiled joining functions.

    Another trick is to use view

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

    The complex values are saved as 2 adjacent floats. So the same databuffer can be viewed as pure floats, or with this view as a 2d array of floats. In contrast to the concatenate functions, there's no copying here.

    Another test on the alternatives is to ask what happens when u is 2d or higher?