2016-06-21 26 views
11

bir df şöyle var:belirlenmesi ardışık olaylar

Count 
1 
0 
1 
1 
0 
0 
1 
1 
1 
0 

ve ben Count içinde 1 iki veya daha fazla ardışık olaylar varsa, yeni bir sütunda bir 1 dönmek istiyorum ve bir 0 eğer yok. Bu nedenle, yeni sütunda her satır, Count numaralı sütunda karşılanan bu ölçütlere göre 1 alır. Benim İstenen çıkış sonra olacaktır: her ne kadar içimden

Count New_Value 
1  0 
0  0 
1  1 
1  1 
0  0 
0  0 
1  1 
1  1 
1  1 
0  0 

Ben itertools kullanmanız gerekebilir ama bu konuda okuma edilmiş ve henüz ne gerek rastlamak değil. Bu yöntemi sadece 2 değil aynı zamanda ardışık sayıları saymak için kullanabilmek istiyorum. Örneğin bazen 10 ardışık olayı saymam gerekiyor, sadece buradaki örnekte 2 kullanıyorum.

+0

10 "df ['Count'] [1] == df ['Count'] [1] .shift (1)' ve eğer öyleyse '1',' '' seçeneğini kontrol edin. Sonra bu değerleri (0 veya 1) bir 'dizisine' .append() yapmalısınız. Ardından ilk elemanı ('dizi [0]') '0' (varsayılan) olarak ayarlayın. O zaman dizininizi "dataframe" inize nasıl birleştireceğinizi/birleştireceğinizi/birleştireceğinizi/birleştireceğinizi anlamanız gerekir. % 100 test edilmedi, ama bence bu işe yarayabilir ... :) –

+0

Sorumu çok fazla basitleştirmiş olabilirim, ne olsa 3 ardışık olayı istersem? Bunun işe yaradığını düşünmüyorum. –

cevap

10

Yapabilirsin:

df['consecutive'] = df.Count.groupby((df.Count != df.Count.shift()).cumsum()).transform('size') * df.Count 

almak için: Burada şunları yapabilirsiniz

Count consecutive 
0  1   1 
1  0   0 
2  1   2 
3  1   2 
4  0   0 
5  0   0 
6  1   3 
7  1   3 
8  1   3 
9  0   0 

Herhangi bir eşik değeri için:

threshold = 2 
df['consecutive'] = (df.consecutive > threshold).astype(int) 
0 tek bir aşamada,

Count consecutive 
0  1   0 
1  0   0 
2  1   1 
3  1   1 
4  0   0 
5  0   0 
6  1   1 
7  1   1 
8  1   1 
9  0   0 

veya:

için pandas yöntemlerle

verimliliği açısından
(df.Count.groupby((df.Count != df.Count.shift()).cumsum()).transform('size') * df.Count >= threshold).astype(int) 

sağlar önemli bir hızlanma sorunun büyüklüğü büyüdükçe:

df = pd.concat([df for _ in range(1000)]) 

%timeit (df.Count.groupby((df.Count != df.Count.shift()).cumsum()).transform('size') * df.Count >= threshold).astype(int) 
1000 loops, best of 3: 1.47 ms per loop 

%%timeit 
l = [] 
for k, g in groupby(df.Count): 
    size = sum(1 for _ in g) 
    if k == 1 and size >= 2: 
     l = l + [1]*size 
    else: 
     l = l + [0]*size  
pd.Series(l) 

10 loops, best of 3: 76.7 ms per loop 
+0

İşte bir tek liner: 'df.assign (consecutive = df.Count.groupby ((df.Count! = Df.Count.shift()). Cumsum()). ('size')) sorgu ('ardışık> @ eşik') 'herhangi bir ardışık değerler için çalışacaktır (sadece olanlar ve sıfırlar) – MaxU

1

emin değil bu optimize edilmiş, ancak bir deneyin eğer:

from itertools import groupby 
import pandas as pd 

l = [] 
for k, g in groupby(df.Count): 
    size = sum(1 for _ in g) 
    if k == 1 and size >= 2: 
     l = l + [1]*size 
    else: 
     l = l + [0]*size 

df['new_Value'] = pd.Series(l) 

df 

Count new_Value 
0 1 0 
1 0 0 
2 1 1 
3 1 1 
4 0 0 
5 0 0 
6 1 1 
7 1 1 
8 1 1 
9 0 0