Pandas:使用groupby对象进行循环的有效方法

时间:2013-05-28 16:06:42

标签: python group-by pandas

我有一个非常大的DataFrame,我想做一些重组比较。举个例子,我们可以看看以下示例:

df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
               'B': ['me', 'you', 'me'] * 2,
               'C': [5, 2, 3, 4, 6, 9]})

现在我想按A列进行分组,并有效地循环遍历这些组,并按以下方式进行行式比较:

gb = df.groupby(['A'])

for k, gp in gb:
    for i in arange(len(gp['C'])):
        sum = 0
        for j in arange(len(gp['C'])):
            if (i != j):
                sum = sum + gp['C'].irow(j)
        print gp['C'].irow(i) - sum

是否有可能更有效地执行此操作,并将其结果分配给Dataframe中的单独列。

我非常感谢你的帮助

安迪

1 个答案:

答案 0 :(得分:3)

对我来说似乎有点奇怪,但是IIUC,你的输出是由

给出的
df["weird_C"] = 2*df["C"] - df.groupby("A")["C"].transform(np.sum)

例如:

>>> df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
               'B': ['me', 'you', 'me'] * 2,
               'C': [5, 2, 3, 4, 6, 9]})
>>> df
     A    B  C
0  foo   me  5
1  bar  you  2
2  foo   me  3
3  bar   me  4
4  foo  you  6
5  bar   me  9
>>> df["weird_C"] = 2*df["C"] - df.groupby("A")["C"].transform(np.sum)
>>> df
     A    B  C  weird_C
0  foo   me  5       -4
1  bar  you  2      -11
2  foo   me  3       -8
3  bar   me  4       -7
4  foo  you  6       -2
5  bar   me  9        3

基本上,事情在pandas中工作得更好,你可以在快速矢量化C中一次做得越多。在这种情况下,我们可以立即获取总和,然后减去总和。我们添加的额外位:

>>> df.groupby("A")["C"].sum()
A
bar    15
foo    14
Name: C, dtype: int64

更好的是,我们可以使用transform,以便广播为我们提供一系列的群组总和:

>>> df.groupby("A")["C"].transform(np.sum)
0    14
1    15
2    14
3    15
4    14
5    15
Name: C, dtype: int64

然后因为我们有了该组的总数,并且我们真的想要每个值和其他值之间的差异,我们可以将“x - rest”视为“x + x - x - rest”或“x +” x - (总)“,或”2 * x - 总数“:

>>> 2*df["C"] - df.groupby("A")["C"].transform(np.sum)
0    -4
1   -11
2    -8
3    -7
4    -2
5     3
Name: C, dtype: int64