我遇到了类似的问题,但需要计算平均值和标准差,不包括当前行
由于需要所有值和组的平均值,标准差的计算要困难得多
以下内容可以轻松扩展到 numpy 的任何聚合函数
In [266]: df = pd.DataFrame({"a": np.arange(5) + 1, "b": 2 * (np.arange(5) + 1)})
In [267]: df
Out[267]:
a b
0 1 2
1 2 4
2 3 6
3 4 8
4 5 10
In [268]: import numpy.ma as ma
...: import numpy as np
通过将DataFrame的值堆叠为与行数相同的行来创建一个三维numpy数组。
In [269]: t = np.stack(tuple(df.values for _ in range(len(df.index))), axis=0)
In [270]: t
Out[270]:
array([[[ 1, 2],
[ 2, 4],
[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 1, 2],
[ 2, 4],
[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 1, 2],
[ 2, 4],
[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 1, 2],
[ 2, 4],
[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 1, 2],
[ 2, 4],
[ 3, 6],
[ 4, 8],
[ 5, 10]]])
创建一组堆叠的单位矩阵,用作聚合函数中的掩码(即排除当前行)。
In [271]: e = np.stack(tuple(np.eye(len(df.index)) for _ in range(len(df.columns))), axis=2)
In [272]: e
Out[272]:
array([[[1., 1.],
[0., 0.],
[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[1., 1.],
[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[1., 1.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.],
[1., 1.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.],
[0., 0.],
[1., 1.]]])
从堆叠的数据和标识构建一个掩码数组(numpy.ma.array)。
In [275]: masked_array = ma.array(t, mask=e)
In [276]: masked_array
Out[276]:
masked_array(
data=[[[--, --],
[2, 4],
[3, 6],
[4, 8],
[5, 10]],
[[1, 2],
[--, --],
[3, 6],
[4, 8],
[5, 10]],
[[1, 2],
[2, 4],
[--, --],
[4, 8],
[5, 10]],
[[1, 2],
[2, 4],
[3, 6],
[--, --],
[5, 10]],
[[1, 2],
[2, 4],
[3, 6],
[4, 8],
[--, --]]],
mask=[[[ True, True],
[False, False],
[False, False],
[False, False],
[False, False]],
[[False, False],
[ True, True],
[False, False],
[False, False],
[False, False]],
[[False, False],
[False, False],
[ True, True],
[False, False],
[False, False]],
[[False, False],
[False, False],
[False, False],
[ True, True],
[False, False]],
[[False, False],
[False, False],
[False, False],
[False, False],
[ True, True]]],
fill_value=999999)
最后计算您的聚合值
In [277]: np.nanmean(masked_array, axis=1).data
Out[277]:
array([[3.5 , 7. ],
[3.25, 6.5 ],
[3. , 6. ],
[2.75, 5.5 ],
[2.5 , 5. ]])
In [278]: np.nanstd(masked_array, axis=1).data
Out[278]:
array([[1.11803399, 2.23606798],
[1.47901995, 2.95803989],
[1.58113883, 3.16227766],
[1.47901995, 2.95803989],
[1.11803399, 2.23606798]])