平均函数,不包括Pandas DataFrame中每行的值



是否有一种简单的方法来计算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

最新更新