如何使用numpy查找数组中某个部分的平均值

how to find average of a section in an array using numpy

import numpy as np

temp_array = np.array(
  [[33.5, 35.3, 33.6, 33.6, 33.5, 33.9, 32.3, 33.2, 53.8, 54.6, 53.4, 54.2],
   [33.1, 34.2, 34.1, 34.3, 34.7, 31.3, 32.3, 33.4, 57.5, 55. , 53.5, 56.1],
   [35.3, 35.4, 35.6, 32.6, 33.2, 34.3, 32.8, 33.1, 54.7, 55.4, 54.6, 55.1],
   [34.2, 36.1, 33.5, 32.4, 32.1, 33.5, 34.5, 35. , 53.8, 56.9, 54.5, 54.7],
   [33.4, 33.8, 36.2, 33. , 35. , 34.2, 33.8, 33.8, 55.7, 55.2, 56. , 54.5],
   [34.3, 35.9, 34.4, 34.2, 53.5, 54.2, 55.7, 54. , 56.3, 54.4, 55.5, 53.8],
   [34.7, 35.4, 34.7, 33.1, 53.6, 54.5, 54.4, 55.5, 54.7, 55.4, 55.1, 55.6],
   [33.3, 34.3, 33.6, 33.1, 55.4, 55.7, 55.4, 55.4, 55.8, 55. , 55.3, 54.1],
   [33.7, 33.5, 37. , 34.9, 57.6, 54.2, 54.9, 54.6, 56. , 55.7, 55.1, 55.9],
   [34. , 35.1, 33.6, 34.5, 56.2, 55.3, 55.2, 54. , 54.1, 54.5, 54.4, 56. ]])


    
cell_shape = (5,4)

我想求出该部分的平均值,例如第一部分:

[33.5, 35.3, 33.6, 33.6]
[33.1, 34.2, 34.1, 34.3]
[35.3, 35.4, 35.6, 32.6]
[34.2, 36.1, 33.5, 32.4]
[33.4, 33.8, 36.2, 33. ]

第二节:

[33.5, 33.9, 32.3, 33.2]
[34.7, 31.3, 32.3, 33.4]
[33.2, 34.3, 32.8, 33.1]
[32.1, 33.5, 34.5, 35. ]
[35. , 34.2, 33.8, 33.8] 

等等

sh = temp_array.shape
for y in range(0, sh[0], cell_shape[0]):
    for x in range(0, sh[1], cell_shape[1]):
        print(np.average(temp_array[y:y + cell_shape[0], x:x + cell_shape[1]]))

打印:

34.16
33.49499999999999
54.96
34.365
54.964999999999996
55.135000000000005
for startx, endx in [ ( n * cell_shape[0], (n+1) * cell_shape[0] ) for n in range( temp_array.shape[0] // cell_shape[0] ) ]:
        for starty, endy in [ ( n * cell_shape[1], (n+1) * cell_shape[1] ) for n in range( temp_array.shape[1] // cell_shape[1] ) ]:
                np.average(temp_array[startx:endx, starty:endy])

使用格式为 [startx:endx, starty:endy]

的 np 切片

这只会打印数组,但将其设为平均值只需将其更改为 np.mean

当前的答案工作正常,但如果您想经常在大型阵列上执行此操作,它们可能会很慢。您想要执行的操作称为“使用 mean/uniform 内核的跨步卷积”。有许多库可以比在 Python 中使用 for 循环更快地执行上述操作(例如 PyTorch、scikit-image、or a more advanced numpy way using stride tricks)。

这是一个使用 skimage 的示例,它避免了 Python 中的 for 循环:

import numpy as np
from skimage.util.shape import view_as_windows

temp_array = np.array(
  [[33.5, 35.3, 33.6, 33.6, 33.5, 33.9, 32.3, 33.2, 53.8, 54.6, 53.4, 54.2],
   [33.1, 34.2, 34.1, 34.3, 34.7, 31.3, 32.3, 33.4, 57.5, 55. , 53.5, 56.1],
   [35.3, 35.4, 35.6, 32.6, 33.2, 34.3, 32.8, 33.1, 54.7, 55.4, 54.6, 55.1],
   [34.2, 36.1, 33.5, 32.4, 32.1, 33.5, 34.5, 35. , 53.8, 56.9, 54.5, 54.7],
   [33.4, 33.8, 36.2, 33. , 35. , 34.2, 33.8, 33.8, 55.7, 55.2, 56. , 54.5],
   [34.3, 35.9, 34.4, 34.2, 53.5, 54.2, 55.7, 54. , 56.3, 54.4, 55.5, 53.8],
   [34.7, 35.4, 34.7, 33.1, 53.6, 54.5, 54.4, 55.5, 54.7, 55.4, 55.1, 55.6],
   [33.3, 34.3, 33.6, 33.1, 55.4, 55.7, 55.4, 55.4, 55.8, 55. , 55.3, 54.1],
   [33.7, 33.5, 37. , 34.9, 57.6, 54.2, 54.9, 54.6, 56. , 55.7, 55.1, 55.9],
   [34. , 35.1, 33.6, 34.5, 56.2, 55.3, 55.2, 54. , 54.1, 54.5, 54.4, 56. ]])

cell_shape = (5,4)
sections: np.ndarray = view_as_windows(temp_array, cell_shape, cell_shape)
print(sections.mean((-2,-1)))

结果:

[[34.16  33.495 54.96 ]
 [34.365 54.965 55.135]]