dato un array di numeri interi come
[1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5]
Devo mascherare elementi che si ripetono più N
volte. Per chiarire: l'obiettivo principale è recuperare l'array di maschere booleane, per usarlo in seguito per i calcoli di binning.
Ho trovato una soluzione piuttosto complicata
import numpy as np
bins = np.array([1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5])
N = 3
splits = np.split(bins, np.where(np.diff(bins) != 0)[0]+1)
mask = []
for s in splits:
if s.shape[0] <= N:
mask.append(np.ones(s.shape[0]).astype(np.bool_))
else:
mask.append(np.append(np.ones(N), np.zeros(s.shape[0]-N)).astype(np.bool_))
mask = np.concatenate(mask)
dare ad es
bins[mask]
Out[90]: array([1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5])
C'è un modo migliore per farlo?
EDIT, # 2
Grazie mille per le risposte! Ecco una versione ridotta del diagramma di riferimento di MSeifert. Grazie per avermi indicato simple_benchmark
. Mostra solo le 4 opzioni più veloci:
Conclusione
L'idea proposta da Florian H , modificata da Paul Panzer sembra essere un ottimo modo per risolvere questo problema in quanto è piuttosto semplice e diretto numpy
. Se stai bene con l'utilizzo numba
, tuttavia, la soluzione di MSeifert supera l'altro.
Ho scelto di accettare la risposta di MSeifert come soluzione in quanto è la risposta più generale: gestisce correttamente array arbitrari con blocchi (non unici) di elementi ripetitivi consecutivi. Nel caso in cui numba
sia un no-go, vale la pena dare una risposta anche a Divakar !