Grzegorz Chrupała
Grzegorz Chrupała

Reputation: 3083

What is the equivalent of numpy.allclose for structured numpy arrays?

Running numpy.allclose(a, b) throws TypeError: invalid type promotion on structured arrays. What would be the correct way of checking whether the contents of two structured arrays are almost equal?

Upvotes: 3

Views: 1601

Answers (2)

hpaulj
hpaulj

Reputation: 231540

np.allclose does an np.isclose followed by all(). isclose tests abs(x-y) against tolerances, with accomodations for np.nan and np.inf. So it is designed primarily to work with floats, and by extension ints.

The arrays have to work with np.isfinite(a), as well as a-b and np.abs. In short a.astype(float) should work with your arrays.

None of this works with the compound dtype of a structured array. You could though iterate over the fields of the array, and compare those with isclose (or allclose). But you will have ensure that the 2 arrays have matching dtypes, and use some other test on fields that don't work with isclose (eg. string fields).

So in the simple case

all([np.allclose(a[name], b[name]) for name in a.dtype.names])

should work.

If the fields of the arrays are all the same numeric dtype, you could view the arrays as 2d arrays, and do allclose on those. But usually structured arrays are used when the fields are a mix of string, int and float. And in the most general case, there are compound dtypes within dtypes, requiring some sort of recursive testing.

import numpy.lib.recfunctions as rf

has functions to help with complex structured array operations.

Upvotes: 4

Eric
Eric

Reputation: 97641

Assuming b is a scalar, you can just iterate over the fields of a:

all(np.allclose(a[field], b) for field in a.dtype.names)

Upvotes: 0

Related Questions