为什么pandas groupby().transform()需要一个唯一索引?

pat*_*rry 11 python 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
Run Code Online (Sandbox Code Playgroud)

给出了预期的:

     a   b   partials
0    1   1   1
1    1   2   3
2    2   3   3
3    3   4   4
4    3   5   9
Run Code Online (Sandbox Code Playgroud)

但如果'a'是关键,那一切都会出错:

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
Run Code Online (Sandbox Code Playgroud)

如果在分组前选择列'b',则相同的错误,即.

df['b'].groupby(level=0).transform(np.cumsum)
Run Code Online (Sandbox Code Playgroud)

但是如果你改变整个数据框,你可以使它工作,如:

df.groupby(level=0).transform(np.cumsum)
Run Code Online (Sandbox Code Playgroud)

甚至是一列数据帧(而不是系列):

df.groupby(level=0)[['b']].transform(np.cumsum)
Run Code Online (Sandbox Code Playgroud)

我觉得GroupBy-fu的某些部分仍然是我缺少的.有人能让我直截了当吗?

And*_*den 5

这是一个错误,因为修复了大熊猫(肯定在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
Run Code Online (Sandbox Code Playgroud)

并且您可以将其分配给df中的列

In [12]: df['partial'] = g.apply(np.cumsum)
Run Code Online (Sandbox Code Playgroud)

  • @patricksurry tranform期望一个结果到组中的所有内容,而apply期望组中每一行的值.虽然这两个组的行为(子DataFrames)因此有点混乱. (2认同)