Narasimha Gundavarapu
Narasimha Gundavarapu

Reputation: 43

Can np.abs take input array of dtype=[('real', '<f8'), ('imag', '<f8')] and give the absolute value?

I'm trying to port some code from MATLAB to Python. MATLAB uses abs(data) to get absolute values for complex numbers in the data. I got that into an ndarray(dim - (151402, 16, 64)) using the h5py module. This array contains real and imag values and I want to compute the absolute values for them. Numpy documentation suggests np.abs is the function for it but when used on this ndarray, I get this

error --> `numpy.core._exceptions.UFuncTypeError: ufunc 'absolute' did 
not contain a loop with signature matching types 
dtype([('real', '<f8'), ('imag', '<f8')]) -> dtype([('real', '<f8'), ('imag', '<f8')])`. 

Does this mean np.abs cannot compute absolute values for this data?

Upvotes: 1

Views: 1515

Answers (1)

hpaulj
hpaulj

Reputation: 231385

For a complex dtype array, np.abs produces the magnitude, as explained in its docs:

In [18]: x= np.array(1.1 - 0.2j)
In [19]: x
Out[19]: array(1.1-0.2j)
In [20]: x.dtype
Out[20]: dtype('complex128')
In [21]: np.abs(x)
Out[21]: 1.118033988749895

But you have constructed (or loaded) the complex array as a structured array, with separate real and imag fields. np.abs isn't defined for such a compound dtype (most calculations/ufunc don't work with structured arrays).

In [23]: dt = np.dtype([('real', '<f8'), ('imag', '<f8')])
In [24]: y = np.array((1.1, -0.2), dt)
In [25]: y
Out[25]: array((1.1, -0.2), dtype=[('real', '<f8'), ('imag', '<f8')])
In [26]: np.abs(y)
Traceback (most recent call last):
  File "<ipython-input-26-e2973663f413>", line 1, in <module>
    np.abs(y)
UFuncTypeError: ufunc 'absolute' did not contain a loop with signature matching types dtype([('real', '<f8'), ('imag', '<f8')]) -> dtype([('real', '<f8'), ('imag', '<f8')])

convert to complex dtype:

In [27]: np.abs(y['real']+y['imag']*1j)
Out[27]: 1.118033988749895

Alternatively we could use view to convert the dtype:

In [28]: y.view('complex')
Out[28]: array(1.1-0.2j)
In [29]: np.abs(y.view('complex'))
Out[29]: 1.118033988749895

view doesn't always work with compound dtypes, but here the underlying data byte layout is the same.

Upvotes: 1

Related Questions