多变量Groupby

2024-09-28 22:04:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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"]))

然后(2),编写一些代码,将我的原始df在日期和动物类型之间分割,按中间高度分割,然后返回我想要测量的东西:

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"]

但我想不出如何修复它。任何想法都将不胜感激

谢谢


Tags: 代码类型dfdate高度jancatcols
1条回答
网友
1楼 · 发布于 2024-09-28 22:04:58

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

df.loc[
    df['Height'].gt(df.groupby(['Date', 'Animal'])['Height'].transform('median')), :
].groupby(['Date', 'Animal']).mean().unstack()

当然,您可以通过选择第二个groupby,f.i.之后(或之前)的Weight列来获得Weight的平均值,方法是将最后一行更改为:].groupby(['Date', 'Animal'])[['Weight']].mean().unstack(),在'Weight'周围的双括号保留df维度/结构

逐步:

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

只有当groupby.median()支持level-参数时,才能避免第二个groupby。但是由于groupby方法不支持level,因此需要第二个groupby

相关问题 更多 >