2012-12-21 14 views
20

türünde grouped zaman serisi nesnesine sahibim. grouped.sum() istenilen sonucu verir, ancak groupby nesnesiyle çalışmak için rolling_sum alamıyorum. Yuvarlama işlevlerini groupby nesnesine uygulamak için herhangi bir yol var mı? Örneğin:Python - GroupBy nesnesi için yuvarlama işlevleri

x = range(0, 6) 
id = ['a', 'a', 'a', 'b', 'b', 'b'] 
df = DataFrame(zip(id, x), columns = ['id', 'x']) 
df.groupby('id').sum() 
id x 
a 3 
b 12 

Ancak, ben böyle bir şey istiyorum: Ben mekaniğinin emin değilim

id x 
0 a 0 
1 a 1 
2 a 3 
3 b 3 
4 b 7 
5 b 12 
+0

Yuvarlanma işlevinin gruplanmış nesneler üzerinde nasıl çalışmasını beklersiniz? ou sembollerde yapmak ister misin? – tacaswell

+0

Üzgünüm Daha açık olmalıydım. – ezbentley

+0

Yani, her grupta bir "cumsum" yapmak ve daha sonra her şeyi tek bir veri çerçevesine geri mi uygulamak istiyorsunuz? – tacaswell

cevap

25
In [16]: df.groupby('id')['x'].apply(pd.rolling_mean, 2, min_periods=1) 
Out[16]: 
0 0.0 
1 0.5 
2 1.5 
3 3.0 
4 3.5 
5 4.5 

In [17]: df.groupby('id')['x'].cumsum() 
Out[17]: 
0  0 
1  1 
2  3 
3  3 
4  7 
5 12 
+8

pd.rolling_mean şimdi Series için kullanımdan kaldırıldı ve kaldırılacak, 'df.groupby ('id') ['x'] 'i kullanın. Yuvarlama (2) .mean()' yerine – kekert

1

, ancak bu çalışır. Not, döndürülen değer sadece bir ndarray. Bu şekilde kümülatif veya "haddeleme" fonksiyonunu uygulayabileceğinizi düşünüyorum ve aynı sonuca sahip olmalı.

cumprod, cummax ve cummin ile test ettim ve hepsi bir ndarray verdi. Bence pandalar bu fonksiyonların bir seri döndürdüğünü ve bu sayede fonksiyonun bir toplanma yerine bir dönüşüm olarak uygulandığını bilecek kadar akıllıdır.

In [35]: df.groupby('id')['x'].cumsum() 
Out[35]: 
0  0 
1  1 
2  3 
3  3 
4  7 
5 12 

Düzenleme: buldum meraklı bu sözdizimi Series dönmek yapar:

tarihinde @ kekert en comment ilgili olarak: bu eski soru üzerine gelip Google'cuların için

In [54]: df.groupby('id')['x'].transform('cumsum') 
Out[54]: 
0  0 
1  1 
2  3 
3  3 
4  7 
5 12 
Name: x 
22

@ Garrett'ın yeni

df.groupby('id')['x'].rolling(2).mean() 

merakla

df.groupby('id')['x'].apply(pd.rolling_mean, 2, min_periods=1) 

artık kullanım dışı ziyade,() yaklaşımı daha sonra çoklu endeksli ilk group_by sütuna göre endeksli serisi ve endeks döndüren yeni .rolling(). Yani görünüyor. Eski yaklaşım, orijinal df dizini tarafından tekil olarak indekslenen bir diziyi döndürürken, bu da belki daha az mantıklıdır, ancak bu dizileri orijinal veri çerçevesine yeni bir sütun olarak eklemeyi çok kolaylaştırmıştır.

yüzden ben hala yeni haddeleme() yöntemini kullanır ve bir çözüm olduğunu çözdüm aynı şekilde çalışır: Size serisini

0 0.0 
1 0.5 
2 1.5 
3 3.0 
4 3.5 
5 4.5 

vermelidir

df.groupby('id')['x'].rolling(2).mean().reset_index(0,drop=True) 

hangi sizi sütun olarak ekleyebilirsiniz:

df['x'] = df.groupby('id')['x'].rolling(2).mean().reset_index(0,drop=True) 
+0

' .transform' kullanabilirsiniz. reset_index yerine? – TMrtSmith

+1

Birden çok sütunla gruplanıyorsanız, bu gerçekten başarısız olur. İlk argümanı (seviyeleri) düşürmek, tüm seviyeleri varsayılan olarak kaldırdığı için bunu çözer. Yani satır "df ['x'] = df.groupby ('id') ['x'] olur. Yuvarlama (2) .mean(). Reset_index (drop = True)' –