2013-05-01 13 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) 

か(というシリーズより)1列のデータフレーム:

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

I GroupBy-fuのいくつかの深い部分が残っているように感じる。誰かが私をまっすぐにすることができます

+0

の列にこれを割り当てることができます - :


回避策として

、以前のパンダにあなたはapply使用することができます「a」のグループ内の「b」の部分和。上記の図を明確にしました。私の実際の例では、 'a'はタイムスタンプであり、bは他のいくつかのキーです。したがって、私のデータセットは実際には異なる長さのタイムシリーズのコレクションです(時間が重複し、グループ内やグループ間でタイムスタンプが重複します)。私は移動平均のような各時系列セグメントの累積演算を行うためにtransform()を使用しています。 – patricksurry

答えて

5

これはバグで、パンダで修正されています(確かに0.15.2、IIRCでは0.14で修正されています)ので、この例外は表示されません。

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

+0

@patricksurryバグかどうかは、変換カテゴリに収まるように思えます... –

+2

@patricksurry tranformはグループ内のすべてのものに対して1つの結果を期待していますが、applyは各行の値を期待していますグループ。両方のグループの動作(サブDataFrames)ので、少し混乱している。 –

関連する問題