biorąc pod uwagę tablicę liczb całkowitych takich jak
[1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5]
Muszę zamaskować elementy, które powtarzają się więcej niż N
razy. Wyjaśnienie: głównym celem jest odzyskanie tablicy maski logicznej, aby później użyć jej do obliczeń binningu.
Wymyśliłem dość skomplikowane rozwiązanie
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)
podając np
bins[mask]
Out[90]: array([1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5])
Czy jest na to lepszy sposób?
EDYCJA, # 2
Wielkie dzięki za odpowiedzi! Oto szczupła wersja wykresu porównawczego MSeifert. Dzięki za wskazanie mnie do simple_benchmark
. Pokazuje tylko 4 najszybsze opcje:
Wniosek
Pomysł zaproponowany przez Floriana H , zmodyfikowany przez Paula Panzera, wydaje się być świetnym sposobem na rozwiązanie tego problemu, ponieważ jest dość prosty i numpy
tylko. Jeśli jesteś w porządku z użyciem numba
jednak rozwiązanie MSeifert za wyprzedza drugiego.
Zdecydowałem się zaakceptować odpowiedź MSeiferta jako rozwiązanie, ponieważ jest to bardziej ogólna odpowiedź: poprawnie obsługuje dowolne tablice z (nieunikalnymi) blokami kolejnych powtarzających się elementów. Na wypadek, gdyby numba
było to niemożliwe, odpowiedź Divakara również jest warta obejrzenia!