I think you might want to do the following, depending on what's inside the object type and if there's no padding to worry about:
bane.view(np.complex64) or
bane.view(np.complex128)
However if that does not work, which it didn't for some small tuple example I tried, the following worked:
bane.astype(np.float).view(np.complex64)
Consider using numpy structures rather than objects for the base dtype, you may have an easier time over all.
Answer from Jason Newton on Stack OverflowI 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?
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.
You could export binary reals from Python and Import "Real64".
Convert Python's numpy.ndarray myArray of complex numbers into reals of their real and imaginary parts and export binary with.
myArray.view(float).tofile("exampleArrayBinary")
Then Import with
r = Import[
FileNameJoin[{$UserDocumentsDirectory, "exampleArrayBinary"}]
, "Real64"
];
The import should hold $1000 \times 1000 \times 2 = 2000000$ items
Dimensions@r
{2000000}
Partition into pairs and Apply Complex
r = Complex @@@ Partition[r, 2];
r[[1]]
2.41713 +2.45023 I
The 100000 complex numbers are recovered.
Import "Real64" is instantaneous for this example. However, you do lose the dimensions of the array.
An alternative would be to
- find a Python library for a file type that that supports matrix exports and has support in Wolfram Language, like
"MAT". - Convert Python's array to reals and export the matrix
- Import into Mathematica and partition & convert each row as above.
Hope this helps.
You don't need to export and then import that. Just use the ExternalEvaluate functionality or an ExternalLanguageCell (on mac: Shift + .):

exampleArray = ExternalEvaluate["Python", "import numpy as np
import numpy.random
myArray = np.zeros((1000,1000),dtype='complex')
for (i,k) in enumerate(myArray):
myArray[i] = numpy.random.normal(0,1,1000)+1J*numpy.random.normal(0,1,1000)
myArray
"]
