2013-05-01 91 views
11

我想使用groupby()。transform()對(排序的)數據集中的每個記錄塊進行自定義(累積)變換。除非我確保我有一個唯一的密鑰,否則它不起作用。爲什麼?爲什麼pandas groupby()。transform()需要一個唯一的索引?

這裏的玩具例子:

df = pd.DataFrame([[1,1], 
        [1,2], 
        [2,3], 
        [3,4], 
        [3,5]], 
        columns='a b'.split()) 
df['partials'] = df.groupby('a')['b'].transform(np.cumsum) 
df 

給出預期:

,但如果 '一' 是一個關鍵,這一切都錯了:

df = df.set_index('a') 
df['partials'] = df.groupby(level=0)['b'].transform(np.cumsum) 
df 

--------------------------------------------------------------------------- 
Exception         Traceback (most recent call last) 
<ipython-input-146-d0c35a4ba053> in <module>() 
     3 
     4 df = df.set_index('a') 
----> 5 df.groupby(level=0)['b'].transform(np.cumsum) 

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/core/groupby.pyc in transform(self, func, *args, **kwargs) 
    1542    res = wrapper(group) 
    1543    # result[group.index] = res 
-> 1544    indexer = self.obj.index.get_indexer(group.index) 
    1545    np.put(result, indexer, res) 
    1546 

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/core/index.pyc in get_indexer(self, target, method, limit) 
    847 
    848   if not self.is_unique: 
--> 849    raise Exception('Reindexing only valid with uniquely valued Index ' 
    850        'objects') 
    851 

Exception: Reindexing only valid with uniquely valued Index objects 

同樣的錯誤如果您在分組之前選擇列'b',即。

df['b'].groupby(level=0).transform(np.cumsum) 

,但你可以做,如果你改變了整個數據框,就像它的工作:

df.groupby(level=0).transform(np.cumsum) 

甚至一列數據框(而不是系列):

df.groupby(level=0)[['b']].transform(np.cumsum) 

我感覺好像還有一些GroupBy-fu的深層部分,我很想念。有人能讓我挺身而出嗎?

+0

分配這列是的,這就是我想要的 - 'a'組中'b'的部分和。我澄清了上面的插圖。在我的實際示例中,'a'是時間戳,b是其他一些鍵,所以我的數據集實際上是一組不同長度的時間序列(它們在時間上重疊並且在組內和組之間包含重複的時間戳)。我正在使用transform()在每個時間片段上執行累積操作,如移動平均值等。 – patricksurry 2013-05-01 10:23:06

回答

5

這是一個bug,因爲固定在熊貓(當然在0.15.2,IIRC固定在0.14),所以你不應該再看到這個例外。


作爲一種變通方法,在早期的熊貓,你可以使用apply

In [10]: g = df.groupby(level=0)['b'] 

In [11]: g.apply(np.cumsum) 
Out[11]: 
a 
1 1 
1 3 
2 3 
3 4 
3 9 
dtype: int64 

,您可以在DF

In [12]: df['partial'] = g.apply(np.cumsum) 
+0

很酷,謝謝 - 我想我不明白apply()和transform()之間的區別。改變某種程度上更嚴格? – patricksurry 2013-05-01 10:58:51

+0

@patricksurry我在想,如果它是一個錯誤,它肯定看起來應該適合變換類別... – 2013-05-01 11:34:30

+2

@patricksurry變換期望一個結果到組中的所有東西,而apply應用期望每行的值在羣組。雖然這兩個組的行爲(子DataFrames),所以它有點混亂。 – 2013-10-23 20:51:15

相關問題