【发布时间】:2019-01-10 05:27:02
【问题描述】:
有没有更有效的方法来确定给定 numpy 数组中某个区域的平均值?为简单起见,假设我有一个 5x5 数组:
values = np.array([[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8]])
假设数组环绕,我想获得每个坐标的平均值,具有指定的区域大小。假设某个区域的大小为2,因此将考虑距离 2 内某个点周围的任何东西。例如,要从坐标(2,2)得到区域的平均值,我们需要考虑
2,
2, 3, 4,
2, 3, 4, 5, 6
4, 5, 6,
6,
因此,平均值将为4.
对于坐标 (4, 4) 我们需要考虑:
6,
6, 7, 3,
6, 7, 8, 4, 5
3, 4, 0,
5,
因此平均值将为4.92.
目前,我有以下代码。但由于我有一个 for 循环,我觉得它可以改进。有没有办法只使用 numpy 内置函数?
有没有办法使用 np.vectorize 来收集子数组(区域),把它全部放在一个数组中,然后使用 np.einsum 什么的。
def get_average(matrix, loc, dist):
sum = 0
num = 0
size, size = matrix.shape
for y in range(-dist, dist + 1):
for x in range(-dist + abs(y), dist - abs(y) + 1):
y_ = (y + loc.y) % size
x_ = (x + loc.x) % size
sum += matrix[y_, x_]
num += 1
return sum/num
class Coord():
def __init__(self, x, y):
self.x = x
self.y = y
values = np.array([[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8]])
height, width = values.shape
averages = np.zeros((height, width), dtype=np.float16)
for r in range(height):
for c in range(width):
loc = Coord(c, r)
averages[r][c] = get_average(values, loc, 2)
print(averages)
输出:
[[ 3.07617188 2.92382812 3.5390625 4.15234375 4. ]
[ 2.92382812 2.76953125 3.38476562 4. 3.84570312]
[ 3.5390625 3.38476562 4. 4.6171875 4.4609375 ]
[ 4.15234375 4. 4.6171875 5.23046875 5.078125 ]
[ 4. 3.84570312 4.4609375 5.078125 4.921875 ]]
【问题讨论】:
标签: python numpy vectorization