2017-12-12 207 views
7

I (ardışık mesures temsil eden) sinyallerinin bir listesi var değer tutmak: Python listesi yalnızca eşit eğer n öncülleri

signals = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0] 

Ben sadece önceki n tedbirler gereği eşit eğer bir sinyal geçerli düşünün.

Ör. (n=2) numaralı validasyon için sadece 2 meseleyi düşünürsek, ilk zaman sinyalleri 0'dan 1'e döner, biz hala 0'tır, ancak sonraki mesaiyi, eğer tekrar 1 ise, o zaman hala geçerli olduğunu düşünür ve yaparız 1. Sonra 2'ye ihtiyacımız olacak 0 için tekrar 0'a çevirme, vb ... Burada basitleştirme için sinyaller 0 ve 1'dir, fakat benim uygulamada diğer tamsayılar olabilirler.

İstenilen çıktı: Bunu yapmanın bir Pythonesque tek satırlık yol arıyordu ama istenen çıktıyı bulmak için görünmüyor olabilir

# For n = 2: 
valid_s = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0] 

# For n = 3: 
valid_s = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0] 

# For n = 4: 
valid_s = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0] 

.

S = signals 

# For n = 2 
[S[i] if S[i] == S[i-1] else S[i-2] for i, _ in enumerate(S)] 
# gives [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0] 

# For n = 3 
[S[i] if S[i] == S[i-1] == S[i-2] else S[i-3] for i, _ in enumerate(S)] 
# gives [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0] 

Edit: Ben çizgisinde bir şey denedim zaten aktardıktan olarak bu kolaylaştırıyor eğer numpy açığım.

+0

n = 2 doğru için istediğiniz çıktı mı: benim yeni yaklaşım tamamladıktan sonra şimdi bunun @tobias_k zaten onun cevabını uygulanan aynı fikir olduğunu düşünüyorum? Çıktınızı sadece ölçülen değerlere mi yoksa zaten "düzeltilmiş" önceki değerlere mi dayalıyorsunuz? – voiDnyx

+0

Evet, n = 2 için 1 veya 0'a geçiş yapmayı düşünmek için iki ardışık 1 veya 0'a ihtiyacım var. İki ardışıkım yoksa, önceden onaylanmış olan değeri korurum. Bu nedenle n = 2 için istenen çıktı. – Fredovsky

cevap

5

Bunu tek liner/liste olarak anlamanın iyi bir yolu olduğunu düşünmüyorum. all değerini, listenin bir dilimiyle, değerin n değerleriyle aynı olup olmadığını görmek için kullanabilseniz de, bunun geçerli olmadığı durumda son geçerli değerin hangisi olduğunu belirlemenin iyi bir yolunu göremiyorum.

Bunun yerine, döngü için iyi bir eski "Birçok-çizgileri" kullanabilirsiniz:

signals = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0] 
n = 3 

last_valid = 0 
current = None 
repeated = 0 
res = [] 
for s in signals: 
    if s == current: 
     repeated += 1 
    else: 
     repeated = 1 
     current = s 
    if repeated >= n: 
     last_valid = s 
    res.append(last_valid) 

Sonrasında resitertools.groupby kullanılarak [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]


Alternatif

, biraz daha kısa olduğu; Sonuç aynıdır:

last_valid = 0 
res = [] 
for k, g in itertools.groupby(signals): 
    m = len(list(g)) 
    if m >= n: 
     res.extend([last_valid] * (n-1) + [k] * (m-n+1)) 
     last_valid = k 
    else: 
     res.extend([last_valid] * m) 
+2

Ek: Her zaman olduğu gibi, tek satırlık bir çözüm istiyorsanız, sadece bir işlev haline getirin. ;-) –

+0

Biraz daha kısa ve belki daha basit: https://ideone.com/vtjVUW –

+1

Ah, * çok * daha kısa/basit: https://ideone.com/cgEnpu –

2
signal = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0] 

def each(signal, n): 
    p = 0 
    ring = [ signal[0] ] * (n-1) 
    v = None 
    for x in signal: 
    if v is None or all(q == x for q in ring): 
     v = x 
    yield v 
    ring[p] = x 
    p = (p+1) % (n-1) 

list(each(signal, 2)) 
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0] 

Ama bu yeniden ele ve saf iteratif (daha az Pythonic) yaklaşımı muhtemelen daha etkili olduğunu düşünüyorum.

def each(signal, n): 
    current = signal[0] 
    next = None 
    for v in signal: 
    if v != current: 
     if v == next: 
     next_count += 1 
     else: 
     next_count = 1 
     next = v 
     if next_count >= n: 
     current = v 
    yield current 
+0

Neden "yüzük"? Neden sadece listenin bir dilim değil? –

+0

Dilimler oluşturduğundan, muhtemelen bir çalma tutucusunu kullanmaktan daha maliyetlidir. Güvenmek istemediğim uygulamaya bağlı. – Alfe

+0

Geçerli nokta, ancak genel karmaşıklık hala 'O (len (lst) * n) ' –