Python熊猫:使用groupby()和agg()时是否保留顺序?

Python熊猫:使用groupby()和agg()时是否保留顺序?,python,pandas,aggregate,Python,Pandas,Aggregate,我经常使用pandas的agg()函数对data.frame的每一列运行摘要统计。例如,下面是如何生成平均值和标准偏差: df = pd.DataFrame({'A': ['group1', 'group1', 'group2', 'group2', 'group3', 'group3'], 'B': [10, 12, 10, 25, 10, 12], 'C': [100, 102, 100, 250, 100, 102

我经常使用pandas的
agg()
函数对data.frame的每一列运行摘要统计。例如,下面是如何生成平均值和标准偏差:

df = pd.DataFrame({'A': ['group1', 'group1', 'group2', 'group2', 'group3', 'group3'],
                   'B': [10, 12, 10, 25, 10, 12],
                   'C': [100, 102, 100, 250, 100, 102]})

>>> df
[output]
        A   B    C
0  group1  10  100
1  group1  12  102
2  group2  10  100
3  group2  25  250
4  group3  10  100
5  group3  12  102
在这两种情况下,将各行发送到agg函数的顺序并不重要。但是请考虑下面的例子,即:

df.groupby('A').agg([np.mean, lambda x: x.iloc[1] ])

[output]

        mean  <lambda>  mean  <lambda>
A                                     
group1  11.0        12   101       102
group2  17.5        25   175       250
group3  11.0        12   101       102
df.groupby('A').agg([np.mean,lambda x:x.iloc[1]])
[输出]
中庸
A.
第1组11.0 12 101 102
第2组17.5 25 175 250
第3组11.0 12 101 102
在这种情况下,lambda按预期工作,输出每组中的第二行。然而,我无法在pandas文档中找到任何暗示这在所有情况下都是真实的内容。我希望将
agg()
与加权平均函数一起使用,因此我希望确保进入函数的行的顺序与它们在原始数据帧中出现的顺序相同

有没有人知道,最好是通过文档或pandas源代码中的某个地方,这是否保证会发生?

请参阅此增强功能

简短的回答是肯定的,groupby将保留传入的订单。你可以用下面的例子来证明这一点:

In [20]: df.sort_index(ascending=False).groupby('A').agg([np.mean, lambda x: x.iloc[1] ])
Out[20]: 
           B             C         
        mean <lambda> mean <lambda>
A                                  
group1  11.0       10  101      100
group2  17.5       10  175      100
group3  11.0       10  101      100
[20]中的
:df.sort_index(升序=False).groupby('A').agg([np.mean,lambda x:x.iloc[1]])
出[20]:
B C
中庸
A.
第11.0 10 101 100组
第2组17.5 10 175 100
第3组11.0 10 101 100
然而,这对于重采样是不正确的,因为它需要一个单调索引(它将与非单调索引一起工作,但将首先对其进行排序)

它们是groupby的
sort=
标志,但这与组本身的排序有关,而与组内的观察值无关

仅供参考:
df.groupby('A').nth(1)
是获取组的第二个值的安全方法(因为如果组有<2个元素,则上述方法将失败)

更简单:

  import pandas as pd
  pd.pivot_table(df,index='A',aggfunc=(np.mean))
输出:

            B    C
     A                
   group1  11.0  101
   group2  17.5  175
   group3  11.0  101
Panda的0.19.1文档称“groupby保留每个组中的行顺序”,因此这是有保证的行为


为了保持顺序,您需要传递
.groupby(…,sort=False)
。在您的情况下,分组列已经排序,因此没有区别,但通常必须使用
sort=False
标志:

 df.groupby('A', sort=False).agg([np.mean, lambda x: x.iloc[1] ])
参考:

API接受“SORT”作为参数

排序参数的说明如下所示:

In [20]: df.sort_index(ascending=False).groupby('A').agg([np.mean, lambda x: x.iloc[1] ])
Out[20]: 
           B             C         
        mean <lambda> mean <lambda>
A                                  
group1  11.0       10  101      100
group2  17.5       10  175      100
group3  11.0       10  101      100
排序:bool,默认为True 对组键进行排序。关闭此选项可获得更好的性能。注:这并不影响各组内观察的顺序Groupby保留每个组中的行顺序


因此,“Groupby”显然保留了每个组中的行顺序。

是的,我看不到任何保证文档中保留了顺序,因此依赖它似乎有点不明智。如果排序由
B
列反映,则可以在lambda中按
B
对每个组进行排序以确保。不幸的是,我希望按未包含在聚合中的列对行进行排序。数据帧在调用
agg()
之前进行排序,因此,如果将其作为
groupby()
的一部分进行重新排序,则这只是一个问题。感谢您的澄清和问题链接!我最初使用
iloc
作为示例,因为我不知道如何将
nth()
传递到
agg()
调用(因为此时
x
是一个系列)。除了作为DataFrame成员函数之外,是否有其他方法调用
nth()
nth
仅在groupby上定义。“除了DataFrame成员函数”是什么意思?我的意思是我不知道如何将
nth()
作为列表中发送到
agg()的函数之一传递给
。您不能执行
.agg([np.mean,nth])
DataFrame.nth()
lambda x:x.nth(2)
。这就是导致我使用iloc的原因,尽管它会抛出索引错误。最好的办法可能是不要一步到位;首先使用
nth()
,然后使用
agg()
,然后合并它们。groupby有一个sort=标志,但这与组本身的排序有关,而不是组内的观察值。考虑到经常使用这个参数,他们应该将其作为默认参数