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)
    
Answer from Warren Weckesser on Stack Overflow
Top answer
1 of 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)
    
2 of 3
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)
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-complex-to-float
Python Complex to Float - GeeksforGeeks
July 23, 2025 - Complex Number: (3+4j) Imaginary Part as Float: 4.0 · In this example, two complex matrices, "matrix_a" and "matrix_b," are multiplied using NumPy dot product function. The resulting complex matrix is stored in "result_matrix," and its real ...
🌐
NumPy
numpy.org › doc › stable › user › basics.types.html
Data types — NumPy v2.4 Manual
Whether this is possible in numpy ... hardware floating-point with 80-bit precision, and while most C compilers provide this as their long double type, MSVC (standard for Windows builds) makes long double identical to double (64 bits). NumPy makes the compiler’s long double available as numpy.longdouble (and np.clongdouble for the complex ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › using-numpy-to-convert-array-elements-to-float-type
Using NumPy to Convert Array Elements to Float Type - GeeksforGeeks
July 15, 2025 - It’s a form of in-place reassignment, not true in-place conversion which NumPy doesn’t support due to fixed data types . ... Explanation: Here, a is converted to float using astype(float) and reassigned to itself, updating the array without keeping the original.
🌐
GitHub
github.com › numpy › numpy › issues › 23062
BUG: Inconsistent `complex`-->`float` casting failures · Issue #23062 · numpy/numpy
January 22, 2023 - complex cannot be converted to float is reasonable behavior, but the 0d conversions work for complex256 which seems strange. import numpy as np CMP_TYPES = [np.complex64, np.complex128, np.complex256] for cmptype in CMP_TYPES: xarg = np.array(3, ...
Author   HaoZeke
🌐
GitHub
github.com › numpy › numpy › issues › 13007
float(np.complex128) silently drops imaginary part · Issue #13007 · numpy/numpy
February 21, 2019 - Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. ... There was an error while loading. Please reload this page. ... >>> v = 2j >>> float(v) *** TypeError: can't convert complex to float >>> v = np.complex128(2j) >>> float(v) 0.0
Author   goerz
Find elsewhere
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.real.html
numpy.real — NumPy v2.4 Manual
The real component of the complex argument. If val is real, the type of val is used for the output. If val has complex elements, the returned type is float.
🌐
NumPy
numpy.org › doc › 1.22 › user › basics.types.html
Data types — NumPy v1.22 Manual
Whether this is possible in numpy depends on the hardware and on the development environment: specifically, x86 machines provide hardware floating-point with 80-bit precision, and while most C compilers provide this as their long double type, MSVC (standard for Windows builds) makes long double identical to double (64 bits). NumPy makes the compiler’s long double available as np.longdouble (and np.clongdouble for the complex numbers).
🌐
Finxter
blog.finxter.com › 5-best-ways-to-convert-python-complex-to-float
5 Best Ways to Convert Python Complex to Float – Be on the Right Side of Change
The code converts the complex number to a string, splits it at the ‘+’ sign and takes the first part, which it then converts back into a float. NumPy, a popular scientific computing library in Python, provides utilities for handling complex numbers, including extracting their real part ...
🌐
NumPy
numpy.org › devdocs › user › basics.types.html
Data types — NumPy v2.5.dev0 Manual
Whether this is possible in numpy ... hardware floating-point with 80-bit precision, and while most C compilers provide this as their long double type, MSVC (standard for Windows builds) makes long double identical to double (64 bits). NumPy makes the compiler’s long double available as numpy.longdouble (and np.clongdouble for the complex ...
🌐
Python Forum
python-forum.io › thread-22225.html
Complex floating issue
Can anyone make a look to following code why it cant calculate complex numbers in the defined arrray. import numpy as np n=5 alpha = 0.7 A=np.zeros() B=np.zeros() #sum=0 for i in range(n+1): for j in
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.ndarray.real.html
numpy.ndarray.real — NumPy v2.3 Manual
Back to top · Choose version · GitHub · Choose version · GitHub · attribute · ndarray.real# The real part of the array. See also · numpy.real · equivalent function · Examples · Try it in your browser! >>> import numpy as np >>> x = np.sqrt([1+0j, 0+1j]) >>> x.real array([ 1. , 0.70710678]) >>> x.real.dtype dtype('float64') Go BackOpen In Tab ·
Top answer
1 of 3
19

I also deal with lots of complex integer data, generally basebanded data.

I use

dtype = np.dtype([('re', np.int16), ('im', np.int16)])

It's not perfect, but it adequately describes the data. I use it for loading into memory without doubling the size of the data. It also has the advantage of being able to load and store transparently with HDF5.

DATATYPE  H5T_COMPOUND {
    H5T_STD_I16LE "re";
    H5T_STD_I16LE "im";
}

Using it is straightforward and is just different.

x = np.zeros((3,3),dtype)
x[0,0]['re'] = 1
x[0,0]['im'] = 2
x
>> array([[(1, 2), (0, 0), (0, 0)],
>>        [(0, 0), (0, 0), (0, 0)],
>>        [(0, 0), (0, 0), (0, 0)]],
>>  dtype=[('re', '<i2'), ('im', '<i2')])

To do math with it, I convert to a native complex float type. The obvious approach doesn't work, but it's also not that hard.

y = x.astype(np.complex64) # doesn't work, only gets the real part
y = x['re'] + 1.j*x['im']  # works, but slow and big
y = x.view(np.int16).astype(np.float32).view(np.complex64)
y
>> array([[ 1.+2.j,  0.+0.j,  0.+0.j],
>>        [ 0.+0.j,  0.+0.j,  0.+0.j],
>>        [ 0.+0.j,  0.+0.j,  0.+0.j]], dtype=complex64)

This last conversion approach was inspired by an answer to What's the fastest way to convert an interleaved NumPy integer array to complex64?

2 of 3
2

Consider using matrices of the form [[a,-b],[b,a]] as a stand-in for the complex numbers.

Ordinary multiplication and addition of matrices corresponds to addition an multiplication of complex numbers (this subring of the collection of 2x2 matrices is isomorphic to the complex numbers).

I think Python can handle integer matrix algebra.

🌐
NumPy
numpy.org › doc › 2.2 › reference › generated › numpy.imag.html
numpy.imag — NumPy v2.2 Manual
The imaginary component of the complex argument. If val is real, the type of val is used for the output. If val has complex elements, the returned type is float.