Python 多变量分组

Python 多变量分组,python,pandas,group-by,Python,Pandas,Group By,我有一个df,看起来有点像这样: Date Animal Height Weight Jan-00 Cat 102 56 Jan-00 Cat 98 75 Jan-00 Cat 50 100 Jan-00 Cat 46 46 Jan-00 Cat 100 50 我试图找出1-00年猫的平均体重,这比1-00年猫的平均身高还要高。所以在这个例子中,中间高度是9

我有一个df,看起来有点像这样:

Date   Animal   Height   Weight
Jan-00   Cat      102      56
Jan-00   Cat      98       75
Jan-00   Cat      50       100
Jan-00   Cat      46       46
Jan-00   Cat      100      50
我试图找出1-00年猫的平均体重,这比1-00年猫的平均身高还要高。所以在这个例子中,中间高度是98;猫的平均体重超过平均身高是53(平均50,56)。我有很多不同的动物类型,所以我不想手动指定动物类型。随着时间的推移,除了猫的重量之外,我还想测量其他一些东西(因此,我试图在某种程度上证明我的代码)

从StackOverflow开始,我的方法是: (1) 编写一个函数,告诉代码的其余部分我要测量的内容:

def column_index(df, query_cols):
    cols = df.columns.values
    sidx = np.argsort(cols)
    return sidx[np.searchsorted(cols,query_cols,sorter=sidx)]

cols = (column_index(df, ["Weight"]))
x = (df["Height"]
     .gt(df.groupby(["Date","Animal"])["Height"]
     .transform('median')))

df_Tall = df[x].mean(level = 0)[df.columns[cols]]
然后(2),编写一些代码,将我的原始df在日期和动物类型之间分割,按中间高度分割,然后返回我想要测量的东西:

def column_index(df, query_cols):
    cols = df.columns.values
    sidx = np.argsort(cols)
    return sidx[np.searchsorted(cols,query_cols,sorter=sidx)]

cols = (column_index(df, ["Weight"]))
x = (df["Height"]
     .gt(df.groupby(["Date","Animal"])["Height"]
     .transform('median')))

df_Tall = df[x].mean(level = 0)[df.columns[cols]]
然而,当我这样做时,它只返回重量的单个系列数据;我试图获得多个列,每个列代表不同的动物-即我的预期输出应该如下所示:

       Weight
Date   Cat   Animal_x   Animal_y   Animal_z
Jan-00  53     xx          xx         xx 
我想我的错误就像是在排队

.gt(df.groupby(["Date","Animal"])["Height"]
但我想不出如何修复它。任何想法都将不胜感激


谢谢你,你的方法几乎是正确的。我刚刚添加了另一个
groupby
中值过滤身高数据,以
Animal
Date
列对平均体重(和身高)进行分组:

df.loc[
    df['Height'].gt(df.groupby(['Date', 'Animal'])['Height'].transform('median')), :
].groupby(['Date', 'Animal']).mean().unstack()
当然,您可以通过将最后一行更改为:
].groupby(['Date',Animal'])[[['Weight']].mean().unstack(),在第二个
groupby
之后(或之前)选择
Weight
列来获得
重量的平均值,在
的“重量”周围有两个括号
保留df尺寸/结构

逐步:

  • 按日期和动物分组,获得中间值并选择身高更大的位置(与您的问题相同)
  • .loc
    df[x]
    上显式第一轴索引只是我个人的偏好。两者都能很好地根据中间高度过滤数据
  • 第二个groupby在高度过滤数据上,选择groupby之前或之后的重量是可选的
  • 获取每个动物和日期组的平均值
  • unstack将数据帧转换为多索引列,第二级为Animal

只有当
groupby.media()
支持
level
-参数时,才能避免使用第二个groupby。但是,由于(大多数或全部?)groupby方法不支持
级别
,因此需要第二个groupby。

为什么不首先过滤掉身高大于其组中值的动物?在您的情况下,性能是一个问题吗?目前,我对计算的速度并不过分担心(在合理的范围内!)。我原以为术语x=(df[“Height”].gt(df.groupby([“Date”,“Animal”])[“Height”])。transform('media'))可以实现这一点?有没有比这更直截了当的东西我忽略了?那太棒了。非常感谢你!!