2012-09-06 16 views
16

Ho un ndarray numpy con la forma di (30.480.640), il 1 ° e il 2 ° asse che rappresentano le posizioni (latitudine e longitute), l'asse 0 contiene i punti dati effettivi.Voglio utilizzare il valore più frequente lungo l'asse 0 in ogni posizione , che è la costruzione di una nuova matrice a forma di (1.480.640) .ie:Come trovare i valori più frequenti in 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]]]) 

I punti di dati conterranno numeri galleggianti negtive e positivi. Come posso eseguire tali calcoli? Molte grazie!

Ho provato con numpy.unique, ma ho ottenuto "TypeError: unique() ha ottenuto un argomento di parole chiave inaspettate 'return_inverse'". Sto usando numpy versione 1.2.1 installata su Unix e non supporta return_inverse. . Ho anche provato la modalità, ma ci vuole un istante per elaborare una quantità così grande di dati ... quindi c'è un modo alternativo per ottenere i valori più frequenti? Grazie ancora.

+2

Cosa intendi per valore dominante? Non capisco la domanda. –

+0

In secondo luogo il commento di @HenryGomersall - Non ho Scooby quale sia la tua domanda ... –

+0

Scusa per la tua confusione ... Intendevo i valori più frequenti .. – oops

risposta

14

per trovare il valore più frequente di una matrice piatta, utilizzare unique, bincount e 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))] 

Per lavorare con un array multidimensionale, non abbiamo bisogno di preoccuparsi di unique, ma abbiamo bisogno di utilizzare apply_along_axis su 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 i tuoi dati:

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, davvero? È possibile approssimare np.unique(return_inverse=True) ragionevolmente efficiente utilizzando np.searchsorted (si tratta di un O aggiuntivo (n registro n), quindi non dovrebbe cambiare le prestazioni in modo significativo):

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

non l'ho provato ma grazie a sacco! – oops

+0

@ ecatmur, sto usando numpy versione 1.2.1 e non supporta np.unique (return_inverse) .. qualche suggerimento? – oops

+0

@oops vedi sopra, dovrai testarlo da solo perché non ho idea di dove troverei una vecchia versione di numpy;) – ecatmur

0

flatten l'array, quindi creare un collections.Counter da esso. Come al solito, fare particolare attenzione quando si confrontano i numeri in virgola mobile.

4

funzione della modalità Usa 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

Grazie a Taro Sato, ma ci vuole molto molto tempo per elaborare array di grandi dimensioni ..un suggerimento per accelerarlo? – oops

+0

Ok, ho notato che vuoi farlo con i float. Per far ciò, penso che sia necessario un approccio leggermente diverso, dal momento che non ha senso chiedersi quale sia il float più frequente, poiché c'è solo una piccola possibilità che due float coincidano con esperimenti ripetuti. Hai davvero bisogno di trovare una cosa così strana? Conosco (approssimativamente) la distribuzione del campione, quindi ci sono misure migliori da calcolare, come media e mediana, per scoprire quale sia il numero più probabile nel campione. –

+0

la gente usa ancora il pacchetto scipy? Leggi da qualche parte che significa scipy è deprecato.Semplicemente curioso di sapere :) –

Problemi correlati