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]], [...], [...]]
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:
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)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With