Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 862
Nico Schlömer Avatar asked Aug 11 '16 15:08

Nico Schlömer


People also ask

How do you extract real and imaginary parts in Python?

Python converts the real numbers x and y into complex using the function complex(x,y). The real part can be accessed using the function real() and imaginary part can be represented by imag().

How do you reshape 1d array to 2D in Numpy?

convert a 1-dimensional array into a 2-dimensional array by adding new axis. a=np. array([10,20,30,40,50,60]) b=a[:,np. newaxis]--it will convert it to two dimension.

Can Numpy handle complex numbers?

NumPy provides the vdot() method that returns the dot product of vectors a and b. This function handles complex numbers differently than dot(a, b). Example 1: Python3.


2 Answers

You can use column_stack and stack the two 1-D arrays as columns to make a single 2D array.

In [9]: np.column_stack((u.real,u.imag))
Out[9]: 
array([[ 1.,  2.],
       [ 2.,  4.],
       [ 3.,  6.],
       [ 4.,  8.]])
like image 78
Nickil Maveli Avatar answered Sep 22 '22 12:09

Nickil Maveli


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?

like image 27
hpaulj Avatar answered Sep 22 '22 12:09

hpaulj