Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a numpy complex array to a two element float array?

Tags:

python

numpy

I have an ndarray in numpy, which contains complex values. I would like to convert each to two float values. I tried it with array real and imag, but only the real parts are in the outputs

import numpy as np

inp_array = np.array([[1,2+3.j,3,4], [5,6,7+1.j,8], [9,10,11,12]], dtype=np.complex64)

out_array = np.array([np.real(inp_array), np.imag(inp_array)])

I would like to get this result:

[[[1,0],[2,3],[3,0],[4,0]], [...], [...]]
like image 888
Iter Ator Avatar asked Sep 05 '25 01:09

Iter Ator


2 Answers

A simple and efficient way to do this is to make a np.float32 view of the array, and then tweak the view to have shape (m, n, 2), where (m, n) is the shape of inp_array. By using a view, the output array actually uses the same memory as inp_array.

Here's your array inp_array.

In [158]: inp_array = np.array([[1,2+3.j,3,4], [5,6,7+1.j,8], [9,10,11,12]], dtype=np.complex64)

In [159]: inp_array
Out[159]: 
array([[ 1.+0.j,  2.+3.j,  3.+0.j,  4.+0.j],
       [ 5.+0.j,  6.+0.j,  7.+1.j,  8.+0.j],
       [ 9.+0.j, 10.+0.j, 11.+0.j, 12.+0.j]], dtype=complex64)

Make a view of the array with type np.float32. If (m, n) is the shape of inp_array, then v will have shape (m, 2*n).

In [160]: v = inp_array.view(np.float32)

In [161]: v
Out[161]: 
array([[ 1.,  0.,  2.,  3.,  3.,  0.,  4.,  0.],
       [ 5.,  0.,  6.,  0.,  7.,  1.,  8.,  0.],
       [ 9.,  0., 10.,  0., 11.,  0., 12.,  0.]], dtype=float32)

Now reshape to (m, n, 2). (w is what you called out_array.)

In [162]: w = v.reshape(inp_array.shape + (2,))

In [163]: w
Out[163]: 
array([[[ 1.,  0.],
        [ 2.,  3.],
        [ 3.,  0.],
        [ 4.,  0.]],

       [[ 5.,  0.],
        [ 6.,  0.],
        [ 7.,  1.],
        [ 8.,  0.]],

       [[ 9.,  0.],
        [10.,  0.],
        [11.,  0.],
        [12.,  0.]]], dtype=float32)

In [164]: inp_array[1,2]
Out[164]: (7+1j)

In [165]: w[1,2]
Out[165]: array([7., 1.], dtype=float32)

A couple notes:

  • This method assumes that inp_array is "C contiguous". That is, the data in the array is stored in contiguous block of memory in "C" order. This might not be the case if inp_array was created, for example, as a slice of a bigger array.
  • inp_array, v and w are all views of the same block of memory. If you change one in-place, they all change:

    In [171]: w[0, 0, 0] = 99
    
    In [172]: inp_array
    Out[172]: 
    array([[99.+0.j,  2.+3.j,  3.+0.j,  4.+0.j],
           [ 5.+0.j,  6.+0.j,  7.+1.j,  8.+0.j],
           [ 9.+0.j, 10.+0.j, 11.+0.j, 12.+0.j]], dtype=complex64)
    
like image 157
Warren Weckesser Avatar answered Sep 07 '25 12:09

Warren Weckesser


The imaginary parts are there in your output_array, but the dimensions are not in the order you would like.

Try replacing the final line with:

out_array = np.stack([np.real(inp_array), np.imag(inp_array)], axis=-1)

or you could use .transpose:

out_array = np.array([np.real(inp_array), np.imag(inp_array)]).transpose(1, 2, 0)

Both should give output:

> out_array
array([[[  1.,   0.],
        [  2.,   3.],
        [  3.,   0.],
        [  4.,   0.]],

       [[  5.,   0.],
        [  6.,   0.],
        [  7.,   1.],
        [  8.,   0.]],

       [[  9.,   0.],
        [ 10.,   0.],
        [ 11.,   0.],
        [ 12.,   0.]]], dtype=float32)
like image 41
myrtlecat Avatar answered Sep 07 '25 14:09

myrtlecat