gibi bir tamsayı dizisi verildi
[1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5]
N
Defalarca yinelenen öğeleri maskelemem gerekiyor . Açıklığa kavuşturmak için: birincil hedef, daha sonra binning hesaplamaları için kullanmak üzere, boole maske dizisini almaktır.
Oldukça karmaşık bir çözüm buldum
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)
vermek örneğin
bins[mask]
Out[90]: array([1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5])
Bunu yapmanın daha güzel bir yolu var mı?
DÜZENLE, # 2
Cevaplar için çok teşekkürler! İşte MSeifert'in referans grafiğinin ince bir versiyonu. Beni işaret ettiğin için teşekkürler simple_benchmark
. Yalnızca en hızlı 4 seçenek gösteriliyor:
Sonuç
Florian H tarafından değiştirilen, Paul Panzer tarafından değiştirilen fikir , bu sorunu çözmenin harika bir yolu gibi görünüyor, çünkü bu oldukça basit ve numpy
sadece. numba
Bununla birlikte kullanmakta sorun yaşıyorsanız , MSeifert'in çözümü diğerinden daha iyi sonuç verir .
MSeifert'in cevabını daha genel cevap olduğu için çözüm olarak kabul etmeyi seçtim: Ardışık yinelenen elemanların (benzersiz olmayan) blokları ile rastgele dizileri doğru bir şekilde işler. Hareketsiz olması durumunda numba
, Divakar'ın yanıtı da bir göz atmaya değer!