Python Pandas-使用numpy数组对多索引数据帧执行mean()
给定一个包含Numpy数组的多索引数据帧,我想知道如何获取给定索引级别的每列的平均值Python Pandas-使用numpy数组对多索引数据帧执行mean(),python,arrays,pandas,numpy,dataframe,Python,Arrays,Pandas,Numpy,Dataframe,给定一个包含Numpy数组的多索引数据帧,我想知道如何获取给定索引级别的每列的平均值 >>pd.\u版本__ '1.0.5' >>>a=np.数组(范围(20)).重塑(-1,2) >>>d=pd.concat([pd.DataFrame({(i%len(a)//2,i%2):{'a':np.array(v),'b':np.array([4,4])}).T表示枚举(a)中的i,v) >>>d a b 0 0 [0, 1] [4, 4] 1 [2, 3] [4, 4] 1 0
>>pd.\u版本__
'1.0.5'
>>>a=np.数组(范围(20)).重塑(-1,2)
>>>d=pd.concat([pd.DataFrame({(i%len(a)//2,i%2):{'a':np.array(v),'b':np.array([4,4])}).T表示枚举(a)中的i,v)
>>>d
a b
0 0 [0, 1] [4, 4]
1 [2, 3] [4, 4]
1 0 [4, 5] [4, 4]
1 [6, 7] [4, 4]
2 0 [8, 9] [4, 4]
1 [10, 11] [4, 4]
3 0 [12, 13] [4, 4]
1 [14, 15] [4, 4]
4 0 [16, 17] [4, 4]
1 [18, 19] [4, 4]
>>>d['a'].平均数()
数组([9,10.]))
>>>d['b'].平均值()
数组([4,4.]))
到目前为止还不错
问题
当我想对所有列或给定级别的索引执行.mean()
时,就会出现问题
获取数据帧的平均值而不是d[]
序列,我们只获取numpy数组中第一个元素的平均值
>d.平均值()
a 9.0
b 4.0
名称:0,数据类型:float64
我们在尝试特定的索引级别时会出错
>>> d.mean(level=0)
Traceback (most recent call last):
[ ... ]
pandas.core.base.DataError: No numeric types to aggregate
>>> d['a'].mean(level=1)
Traceback (most recent call last):
[ ... ]
pandas.core.base.DataError: No numeric types to aggregate
预期产量
>d.平均值()
a[9,10]
b[4,4]
>>>d.平均值(水平=0)
a b
0 [1, 2] [4, 4]
1 [5, 6] [4, 4]
2 [9, 10] [4, 4]
3 [13, 14] [4, 4]
4 [17, 18] [4, 4]
>>>d['a']平均值(1级)
0 [8, 9]
1 [10, 11]
我知道Pandas不会假装很好地处理Numpy阵列,但在我看来这是一个Pandas bug,但我想知道如何解决它?使用Pandas可能有更简单的方法来实现它。但我发现了这一点:
pd.DataFrame([d.iloc[:,i].mean() for i in range(2)], columns = ["a","b"])
a b
0 9.0 10.0
1 4.0 4.0
pd.DataFrame([[d.iloc[range(2*i,2*i+2),j].mean() for i in range(5)] for j in range(2)], index = ["a","b"]).T
a b
0 [1.0, 2.0] [4.0, 4.0]
1 [5.0, 6.0] [4.0, 4.0]
2 [9.0, 10.0] [4.0, 4.0]
3 [13.0, 14.0] [4.0, 4.0]
4 [17.0, 18.0] [4.0, 4.0]
pd.DataFrame([d.iloc[range(0,10,2),0].mean(), d.iloc[range(1,10,2),0].mean()], columns = ["a","b"])
a b
0 8.0 9.0
1 10.0 11.0
我又摸了摸脑袋,决定把这部作品分成几个表现良好的系列
def my_平均值(df,level=None):
如果级别不是无:
返回pd.DataFrame({
上校:{
id:series.mean()表示id,df[col]中的系列。groupby(级别=级别)
}对于df.columns.values中的列
})
其他:
返回pd.DataFrame({col:df[col].mean(),用于df.columns.values}中的col)
哪个输出足够接近我需要的
>>> my_mean(d)
0 1
a 9.0 10.0
b 4.0 4.0
>>> my_mean(d, 0)
a b
0 [1.0, 2.0] [4.0, 4.0]
1 [5.0, 6.0] [4.0, 4.0]
2 [9.0, 10.0] [4.0, 4.0]
3 [13.0, 14.0] [4.0, 4.0]
4 [17.0, 18.0] [4.0, 4.0]
>>> my_mean(d, 1)
a b
0 [8.0, 9.0] [4.0, 4.0]
1 [10.0, 11.0] [4.0, 4.0]
以下是生成预期输出的替代方法: 获取多索引级别值:
level_vals_0 = set(d.index.get_level_values(0))
level_vals_1 = set(d.index.get_level_values(1))
生成输出1:
output = {
'a': [d.loc[(level_vals_0, level_vals_1), 'a'].mean()],
'b': [d.loc[(level_vals_0, level_vals_1), 'b'].mean()]
}
pd.DataFrame(output).T
产出1:
a [9.0, 10.0]
b [4.0, 4.0]
生成输出2:
output = {
'a': [d.loc[i, 'a'].mean() for i in level_vals_0],
'b': [d.loc[i, 'b'].mean() for i in level_vals_0]
}
pd.DataFrame(output)
输出:
a b
0 [1.0, 2.0] [4.0, 4.0]
1 [5.0, 6.0] [4.0, 4.0]
2 [9.0, 10.0] [4.0, 4.0]
3 [13.0, 14.0] [4.0, 4.0]
4 [17.0, 18.0] [4.0, 4.0]
a b
0 [8.0, 9.0] [4.0, 4.0]
1 [10.0, 11.0] [4.0, 4.0]
生成输出3:
output = {
'a': [d.loc[(level_vals_0, i), 'a'].mean() for i in level_vals_1],
'b': [d.loc[(level_vals_0, i), 'b'].mean() for i in level_vals_1]
}
pd.DataFrame(output)
输出:
a b
0 [1.0, 2.0] [4.0, 4.0]
1 [5.0, 6.0] [4.0, 4.0]
2 [9.0, 10.0] [4.0, 4.0]
3 [13.0, 14.0] [4.0, 4.0]
4 [17.0, 18.0] [4.0, 4.0]
a b
0 [8.0, 9.0] [4.0, 4.0]
1 [10.0, 11.0] [4.0, 4.0]
谢谢但是,您的答复假设数据帧中的行数。也许我应该提到,我正在寻找一个大小不可知的解决方案。我的实际索引要脏得多,我不能简单地用
范围(一些数字)重新生成索引
我会根据您的数据大小,尝试计算每个案例的一些_数
,一旦您有了它,尝试应用这种方法是的,我想我可以迭代d.index
,但我认为这将是一个巨大的性能损失。我认为这是整洁的。请注意,您为my_mean(d)
生成的输出与您问题中的预期输出略有不同。