2012-09-06 127 views
16

Tengo una numeral ndarray con forma de (30,480,640), el 1 ° y 2 ° eje representa ubicaciones (latitud y longitud), el 0 ° eje contiene puntos de datos reales.Quiero usar el valor más frecuente a lo largo del eje 0 en cada ubicación , que es para construir una nueva matriz con forma de (1480640) .ie:¿Cómo encontrar los valores más frecuentes en numpy ndarray?

>>> data 
array([[[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]], 

     [[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]], 

     [[40, 40, 42, 43, 44], 
     [45, 46, 47, 48, 49], 
     [50, 51, 52, 53, 54], 
     [55, 56, 57, 58, 59]]]) 

(perform calculation) 

>>> new_data 
array([[[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]]) 

Los puntos de datos contendrán los números flotantes negtive y positivos. ¿Cómo puedo hacer esos cálculos? ¡Muchas gracias!

Intenté con numpy.unique, pero obtuve "TypeError: unique() obtuvo un argumento de palabra clave inesperado 'return_inverse'". Estoy usando la versión numpy 1.2.1 instalada en Unix y no es compatible con return_inverse. .También probé el modo, pero lleva una eternidad procesar tanta cantidad de datos ... ¿existe una forma alternativa de obtener los valores más frecuentes? Gracias de nuevo.

+2

¿Qué quiere decir con valor dominante? No entiendo la pregunta. –

+0

Voy a en segundo lugar el comentario de @HenryGomersall - No tengo un Scooby cuál es tu pregunta tampoco ... –

+0

Lo siento por tu confusión ... Me refiero a los valores más frecuentes .. – oops

Respuesta

14

para encontrar el valor más frecuente de una matriz plana, utilice unique, bincount y argmax:

arr = np.array([5, 4, -2, 1, -2, 0, 4, 4, -6, -1]) 
u, indices = np.unique(arr, return_inverse=True) 
u[np.argmax(np.bincount(indices))] 

Para trabajar con una matriz multidimensional, que no tienen que preocuparse por unique, pero necesitamos utilizar apply_along_axis en bincount:

arr = np.array([[5, 4, -2, 1, -2, 0, 4, 4, -6, -1], 
       [0, 1, 2, 2, 3, 4, 5, 6, 7, 8]]) 
axis = 1 
u, indices = np.unique(arr, return_inverse=True) 
u[np.argmax(np.apply_along_axis(np.bincount, axis, indices.reshape(arr.shape), 
           None, np.max(indices) + 1), axis=axis)] 

con sus datos:

data = np.array([ 
    [[ 0, 1, 2, 3, 4], 
    [ 5, 6, 7, 8, 9], 
    [10, 11, 12, 13, 14], 
    [15, 16, 17, 18, 19]], 

    [[ 0, 1, 2, 3, 4], 
    [ 5, 6, 7, 8, 9], 
    [10, 11, 12, 13, 14], 
    [15, 16, 17, 18, 19]], 

    [[40, 40, 42, 43, 44], 
    [45, 46, 47, 48, 49], 
    [50, 51, 52, 53, 54], 
    [55, 56, 57, 58, 59]]]) 
axis = 0 
u, indices = np.unique(arr, return_inverse=True) 
u[np.argmax(np.apply_along_axis(np.bincount, axis, indices.reshape(arr.shape), 
           None, np.max(indices) + 1), axis=axis)] 
array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]) 

NumPy 1.2, ¿en serio? Se puede aproximar np.unique(return_inverse=True) razonablemente eficiente utilizando np.searchsorted (que es una junta adicional (n registro n), por lo que no debe cambiar significativamente el rendimiento):

u = np.unique(arr) 
indices = np.searchsorted(u, arr.flat) 
+0

no lo he probado, pero gracias a ¡mucho! – oops

+0

@ ecatmur, estoy usando numpy versión 1.2.1 y no admite np.unique (return_inverse) .. alguna sugerencia? – oops

+0

@oops mira arriba, tendrás que probarlo tú mismo ya que no tengo ni idea de dónde encontraría una versión tan vieja de numpy;) – ecatmur

0

flatten su matriz, luego construya un collections.Counter de ella. Como de costumbre, tenga especial cuidado al comparar números de coma flotante.

4

función del modo de uso SciPy:

import numpy as np 
from scipy.stats import mode 

data = np.array([[[ 0, 1, 2, 3, 4], 
        [ 5, 6, 7, 8, 9], 
        [10, 11, 12, 13, 14], 
        [15, 16, 17, 18, 19]], 

       [[ 0, 1, 2, 3, 4], 
        [ 5, 6, 7, 8, 9], 
        [10, 11, 12, 13, 14], 
        [15, 16, 17, 18, 19]], 

       [[40, 40, 42, 43, 44], 
        [45, 46, 47, 48, 49], 
        [50, 51, 52, 53, 54], 
        [55, 56, 57, 58, 59]]]) 

print data 

# find mode along the zero-th axis; the return value is a tuple of the 
# modes and their counts. 
print mode(data, axis=0) 
+0

Gracias Taro Sato, pero lleva mucho tiempo procesar grandes matrices ... alguna sugerencia para acelerarlo? – oops

+0

Bien, noté que quieres hacer esto con flotadores. Para hacer eso, creo que se necesita un enfoque ligeramente diferente, ya que realmente no tiene sentido preguntar cuál es el flotador más frecuente, ya que solo hay una pequeña posibilidad de que dos flotadores coincidan con experimentos repetidos. ¿De verdad necesitas encontrar algo tan extraño? Yo conozco (más o menos) la distribución de su muestra, luego hay mejores medidas para calcular, como la media y la mediana, para averiguar cuál es el número más probable en su muestra. –

+0

¿Todavía se usa ampliamente el paquete scipy? Leer en algún lugar que significa desde scipy está en desuso.Sólo curiosidad por saber :) –

Cuestiones relacionadas