NumPy: obtenga min/max de la matriz de registros de valores numéricos

I have a NumPy record array of floats:

import numpy as np
ar = np.array([(238.03, 238.0, 237.0),
               (238.02, 238.0, 237.01),
               (238.05, 238.01, 237.0)], 
              dtype=[('A', 'f'), ('B', 'f'), ('C', 'f')])

How can I determine min/max from this record array? My usual attempt of ar.min() falla con:

TypeError: no se puede realizar reducir con tipo flexible

I'm not sure how to flatten the values out into a simpler NumPy array.

preguntado el 04 de julio de 12 a las 02:07

3 Respuestas

The easiest and most efficient way is probably to VER your array as a simple 2D array of floats:

ar_view = ar.view((ar.dtype[0], len(ar.dtype.names)))

which is a 2D array view on the structured array:

print ar_view.min(axis=0)  # Or whatever…

This method is fast, as no new array is created (changes to ar_view result in changes to ar). It is restricted to cases like yours, though, where all record fields have the same type (float32, here).

One advantage is that this method keeps the 2D structure of the original array intact: you can find the minimum in each "column" (axis=0), por ejemplo.

contestado el 23 de mayo de 17 a las 12:05

I get an Error with float: "ValueError: new type not compatible with array." However, if I use a NumPy float data type like ar.dtype[0] (o dtype('float32')), success! - Mike T

ar.view((ar.dtype[0], len(ar.dtype))) - Mike T

I guess now we would use structured_to_unstructured? - djvg

This is an interesting comment. Note that structured_to_unstructured crea un Un nuevo array and is therefore not fully equivalent to this answer (and is slower). - Eric O Lebigot

tu puedes hacer

# construct flattened ndarray
arnew = np.hstack(ar[r] for r in ar.dtype.names)

to flatten the recarray, then you can perform your normal ndarray operations, like

armin, armax = np.min(arnew), np.max(arnew)

los resultados son

237.0 238.05

fundamentalmente ar.dtype.names gives you the list of recarray names, then you retrieve the array one by one from the names and stack to arnew

Respondido 04 Jul 12, 02:07

np.hstack() is useful if the different fields of the structured array do not have the same type, which is not the case here. For this question, the view() approach (see my answer) is way faster, and also has the advantage of keeping the 2D structure of the original array intact. - Eric O Lebigot

@EOL yep, I thought the op wanted a flattened ndarray so I suggested him use hstack(), but otherwise if the dtypes are uniform and only min/max are needed, sure, view is a lot lot better. - nye17

This may help someone else down the line, but another way to do it that may be more sensible:

import numpy as np
ar = np.array([(238.03, 238.0, 237.0),
              (238.02, 238.0, 237.01),
              (238.05, 238.01, 237.0)], 
              dtype=[('A', 'f'), ('B', 'f'), ('C', 'f')])
arView = ar.view(np.recarray)

which allowed me to just pick and choose. A problem on my end was that the dtype for all my elements were not the same (a rather complicated struct by and large).

Respondido el 02 de junio de 15 a las 04:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.