我遇到了麻烦。
我有一个形状为(3,4,5)的数组,其中包含3个时间步长的值,用于4个指标和5个区域。就本示例而言,可以说此数组为:
values = np.arange(60).reshape(3,4,5)
我还有一个“地图”,显示了5x5网格上5个区域的位置。例如
map = np.array([[1,1,1,2,2],
[1,1,2,2,2],
[3,3,3,2,2],
[3,3,4,4,4],
[3,3,5,5,4]])
我想要得到的是一个数组(result
),该数组按时间步长(3)和指标(4)在5x5网格上显示值(类似于map
)。所以
>>>result.shape
(3,4,5,5)
我希望这是有道理的。
这里是使用np.pad的实现:
values = np.arange(60).reshape(3,4,5)
# I renamed map to mapping, because map is a basic function in python
mapping = np.array([[1,1,1,2,2],
[1,1,2,2,2],
[3,3,3,2,2],
[3,3,4,4,4],
[3,3,5,5,4]])
v0,v1,v2 = values.shape
m0,m1 = mapping.shape
new = np.zeros((v0,v1,m0,m1))
for a in range(v2):
q = values[:,:,a].reshape(v0,v1,1)
r,c = np.where((mapping-1)==a)
npad = ((0,0), (0,0), (0,len(c)-1))
new[:,:,r,c] = np.pad(q, pad_width=npad, mode='symmetric')
[如果我理解正确,values.shape
中的5与(5, 5)
中的map.shape
不相关,而仅与map
中的值范围相关。首先要做的是使map
中的值遵循常规的python索引约定:从零开始计数,而不是从1开始计数。
这里是如何处理形状与值不同的地图的方法:
import numpy as np
m, n, p = 2, 3, 4
values = np.arange(m*n*p).reshape(m, n, p)
map = np.array([
[0, 0, 0, 3, 3, 3],
[0, 0, 1, 3, 3, 2],
[1, 1, 1, 3, 2, 2],
[2, 1, 2, 2, 2, 1],
[2, 2, 2, 2, 1, 1]
])
q, r = map.shape
map_r = map.reshape(q*r)
# result_r: shape (q*r, m, n)
result_r = np.array([values[:, :, i] for i in map_r])
result = result_r.transpose(1, 2, 0).reshape(m, n, q, r)
# test
jq, jp = 4, 5
mapval = map[jq, jp]
print(f'map[{jq}, {jp}] = {mapval}')
print(f'result[:, :, {jq}, {jp}] =\n{result[:, :, jq, jp]}')
print(f'values[:, :, {mapval}] =\n{values[:, :, mapval]}')
输出:
map[4, 5] = 1
result[:, :, 4, 5] =
[[ 1 5 9]
[13 17 21]]
values[:, :, 1] =
[[ 1 5 9]
[13 17 21]]