是否有一种简单的方法来计算pandas DataFrame中每列的平均值,并为每行排除特定值?下面每一行的x
标记了每次迭代中要排除的值:
a b a b a b
0 1 2 0 x x 0 1 2
1 2 4 first loop 1 2 4 second loop 1 x x etc.
2 3 6 ---> 2 3 6 ---> 2 3 6 --->
3 4 8 3 4 8 3 4 8
4 5 10 4 5 10 4 5 10
____________ _____________
col_avg: 3.5 7.0 col_avg: 3.25 6.5
Using only 4 values at each iteration, as the "x" is excluded from data set
导致一个新的DataFrame
a_x b_x
0 3.5 7.0
1 3.25 6.5
2 3.0 6.0
3 2.75 5.5
4 2.5 5.0
感谢/N
从第一步开始,假设我们对求和感兴趣,而不是计算平均值。在这种情况下,我们将沿着每个col添加除当前元素之外的所有元素。另一种看待/解决它的方法是将每个colo上的所有元素相加,然后减去当前元素本身。所以,本质上我们可以得到所有df.sum(0)
列的和然后简单地减去df
,保持轴不变一致的。Broadcasting
将负责一次跨所有cols执行这些操作。
要得到求平均值的第二步,我们只需除以每个冷求和所涉及的元素数,即df.shape[0]-1
。
df_out = (df.sum(0) - df)/float(df.shape[0]-1)
示例运行-
In [128]: df
Out[128]:
a b
0 1 2
1 2 4
2 3 6
3 4 8
4 5 10
In [129]: (df.sum(0) - df)/float(df.shape[0]-1)
Out[129]:
a b
0 3.50 7.0
1 3.25 6.5
2 3.00 6.0
3 2.75 5.5
4 2.50 5.0
要设置所需的列名,执行:df_out.columns = ['a_x','b_x']
.
我遇到了一个类似的问题,但同时需要平均值和标准差,不包括当前行
标准差比较难计算,因为需要所有的和组的平均值
下面的代码可以很容易地扩展到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]])
使用pd.concat()
和drop()
pd.concat([df.drop(r).mean() for r in df.index],keys=df.index).unstack()
或
pd.concat([df.drop(r).mean() for r in df.index],axis=1).T
或
df.apply(lambda x: [np.roll(x,-i)[1:].mean() for i in range(df.shape[0])])
输出: a b
0 3.50 7.0
1 3.25 6.5
2 3.00 6.0
3 2.75 5.5
4 2.50 5.0