查找DataFrame中相邻元素(行和列)的平均值

问题描述 投票:2回答:2

我有一个图像,我根据其像素强度创建了一个DataFrame。从这里,我想创建一个网格,我找到该网格中每个方格内的平均强度,用2x2像素表示。这样做是为了捕获更大的强度区域,以便将它们与背景噪声区分开来。 (我认为包含这个以提供上下文会很好。)

在DataFrame中,这将转化为从一组2个相邻的行和列中查找4个值的平均值。

因此,为了说明问题,我们假设我们有以下DataFrame:

df=pd.DataFrame({'A':(np.linspace(1,4,num=4)),'B':(np.linspace(5,8,num=4)),'C':(np.linspace(9,12,num=4)), 'D':(np.linspace(13,16,num=4))})

从那时起,我们想要创建一个与每个方块的平均值相对应的DataFrame。在这种情况下,它将对应于以下(即,例如,3将是具有值(1,5,2,6)的2x2平方的平均值,11.5将是(9,13,10)的平均值。 14):

df_mean=DataFrame({'A':pd.Series([3,11.5]),'B':pd.Series([5.5,13.5])})

如果问题仍然不清楚,想象一下采用原始DataFrame并在中间画一条垂直线和一条水平线。这将产生4箱。在4个框中的每个框中,您将找到4个值。我想计算每个框的平均值,并将其插入到包含框的方法的新DataFrame中。

PS:不幸的是,我还不知道如何自己显示DataFrame,而不仅仅是代码。打印功能不起作用。我希望这不是太麻烦。

非常感谢你!

python pandas dataframe
2个回答
3
投票

您可以使用底层的numpy数组非常有效地执行此操作:

def square_mean(arr, y, x):
    yy, xx = arr.shape
    vals = arr.reshape(y, yy//y, x, xx//x).mean((1,3))
    return vals

pd.DataFrame(square_mean(df.values, 2, 2))

     0     1
0  3.5  11.5
1  5.5  13.5

这个解决方案的工作原理是因为数组的一些巧妙的重塑,以下是重塑的工作原理:

yy, xx = arr.shape
vals = arr.reshape(2, yy//2, 2, xx//2)
print(vals)

[[[[ 1.  5.]
   [ 9. 13.]]

  [[ 2.  6.]
   [10. 14.]]]


 [[[ 3.  7.]
   [11. 15.]]

  [[ 4.  8.]
   [12. 16.]]]]

如您所见,数组已被重新整形为块,然后我们可以使用它来计算平均值。


此解决方案将缩放到所有输入大小,只需选择x作为沿x轴的块数,并选择y作为沿y轴的块数:

df = pd.DataFrame(np.random.randint(1, 5, (10, 10)))

   0  1  2  3  4  5  6  7  8  9
0  1  3  4  2  3  3  3  2  1  2
1  3  3  4  1  3  4  4  4  1  3
2  2  3  2  2  4  4  1  1  1  1
3  1  2  1  2  1  3  1  1  2  3
4  2  2  3  4  3  2  4  3  4  2
5  3  3  1  4  2  1  2  3  1  3
6  2  1  3  4  3  2  3  4  3  4
7  2  3  4  2  1  1  1  1  3  2
8  4  3  2  2  2  2  2  1  3  3
9  3  2  1  2  1  3  4  2  4  4

我们可以划分为任意数量的块:

square_mean(df.values, 2, 2)

array([[2.44, 2.4 ],
       [2.4 , 2.48]])

square_mean(df.values, 5, 5)

array([[2.5 , 2.75, 3.25, 3.25, 1.75],
       [2.  , 1.75, 3.  , 1.  , 1.75],
       [2.5 , 3.  , 2.  , 3.  , 2.5 ],
       [2.  , 3.25, 1.75, 2.25, 3.  ],
       [3.  , 1.75, 2.  , 2.25, 3.5 ]])

0
投票

只需在底层numpy数组上使用卷积:

import scipy.ndimage
full_conv = scipy.ndimage.filters.convolve(df.values, 0.25*np.ones((2,2)))
strided_conv = full_conv[::2, ::2]

结果:

array([[ 3.5, 11.5],
       [ 5.5, 13.5]])
© www.soinside.com 2019 - 2024. All rights reserved.