2015-12-12 19 views
5

Dato un array numpy 2 x d dimensionale M, voglio contare il numero di occorrenze di ciascuna colonna di M. Cioè, sto cercando una versione generale di bincount.Conteggio delle occorrenze di colonne in serie numpy

Quello che ho provato finora: (1) colonne convertite in tuple (2) tuple Hashed (via hash) ai numeri naturali (3) usati numpy.bincount.

Questo sembra piuttosto goffo. Qualcuno è a conoscenza di un modo più elegante ed efficiente?

+0

Domanda interessante. Non vedo l'ora di vedere nessuna soluzione perché il mio primo e unico pensiero era esattamente quello che hai fatto. – Reti43

+0

Quindi ti aspetti un elenco di colonne univoche e dei loro conteggi? L'ordine delle colonne deve essere preservato? – imp9

+0

Si prega di mostrare il codice dei vostri tentativi. –

risposta

4

È possibile utilizzare collections.Counter:

>>> import numpy as np 
>>> a = np.array([[ 0, 1, 2, 4, 5, 1, 2, 3], 
...    [ 4, 5, 6, 8, 9, 5, 6, 7], 
...    [ 8, 9, 10, 12, 13, 9, 10, 11]]) 
>>> from collections import Counter 
>>> Counter(map(tuple, a.T)) 
Counter({(2, 6, 10): 2, (1, 5, 9): 2, (4, 8, 12): 1, (5, 9, 13): 1, (3, 7, 11): 
1, (0, 4, 8): 1}) 
1

Dato:

a = np.array([[ 0, 1, 2, 4, 5, 1, 2, 3], 
       [ 4, 5, 6, 8, 9, 5, 6, 7], 
       [ 8, 9, 10, 12, 13, 9, 10, 11]]) 
b = np.transpose(a) 
  1. Una soluzione più efficiente di hashing (richiede ancora manipolazione):

    ho creare una vista della matrice con il tipo di dati flessibile np.void (vedi here) tale che ogni riga diventa un singolo elemento. La conversione in questa forma consentirà di operare su np.unique.

    %%timeit  
    c = np.ascontiguousarray(b).view(np.dtype((np.void, b.dtype.itemsize*b.shape[1]))) 
    _, index, counts = np.unique(c, return_index = True, return_counts = True) 
    #counts are in the last column, remember original array is transposed 
    >>>np.concatenate((b[idx], cnt[:, None]), axis = 1) 
    array([[ 0, 4, 8, 1], 
         [ 1, 5, 9, 2], 
         [ 2, 6, 10, 2], 
         [ 3, 7, 11, 1], 
         [ 4, 8, 12, 1], 
         [ 5, 9, 13, 1]]) 
    10000 loops, best of 3: 65.4 µs per loop 
    

    I conteggi allegati alle colonne uniche di a.

  2. La tua soluzione di hashing.

    %%timeit 
    array_hash = [hash(tuple(row)) for row in b] 
    uniq, index, counts = np.unique(array_hash, return_index= True, return_counts = True) 
    np.concatenate((b[idx], cnt[:, None]), axis = 1) 
    10000 loops, best of 3: 89.5 µs per loop 
    

Aggiornamento: La soluzione di Ef è il più efficiente ed elegante.

%%timeit 
Counter(map(tuple, a.T)) 
10000 loops, best of 3: 38.3 µs per loop 
Problemi correlati