4

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]], [...], [...]]
0

3 Answers 3

12

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)
    
Sign up to request clarification or add additional context in comments.

Comments

5

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)

Comments

0

If you want data output exactly as you asked, you are going to have to type cast the data as an int

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 = []
for l in inp_array:
    for e in l:
        out_array.append(([int(np.real(e)), int(np.imag(e))]))
out_array = np.asarray(out_array)
print(out_array)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.