我有一个看起来像这样的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"]
但是我不知道如何解决它。任何想法将不胜感激!
谢谢
答案 0 :(得分:0)
您的方法几乎是正确的。我刚刚添加了另一个groupby
中值过滤后的高度数据,以Animal
和Date
列对平均体重(和身高)进行分组:
df.loc[
df['Height'].gt(df.groupby(['Date', 'Animal'])['Height'].transform('median')), :
].groupby(['Date', 'Animal']).mean().unstack()
当然,您可以通过选择第二个Weight
之后(或之前)的Weight
列来获得groupby
的均值。通过将最后一行更改为:].groupby(['Date', 'Animal'])[['Weight']].mean().unstack()
,并用'Weight'
周围的双括号保留df尺寸/结构。
分步操作:
.loc
在您的df[x]
上明确的第一轴索引只是我个人的偏爱。两者都可以很好地按中值高度过滤数据。仅当groupby.median()
支持level
参数时,才能避免第二个groupby。但是,由于level
不受(大多数还是全部?)groupby方法支持,因此需要第二个groupby。