[英]move values of 3D array knowing new coordinates with mask
我想扩展一个我在Stackoverflow上讨论过的问题。 它正在处理2D numpy数组,我想用三维数组做同样的事情。
我想将2D数组的元素“移动”到新坐标,这些坐标存储在其他2个数组中。 我希望自动化这个,因为实际上我的阵列很大(400x200x100)。 有些值不会找到他的坐标并且不会被使用,其中一些坐标被屏蔽,我在下面的例子中通过使用值0指示。如果坐标被屏蔽,我想要重新洗牌的数组中的元素将不会使用。
import numpy as np
#My new coordinates in X and Y directions
mx = np.array([[[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.]],
[[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.],
[ 1., 2., 3., 4., 0.]]])
my = np.array([[[ 0., 2., 2., 2., 2.],
[ 0., 3., 3., 3., 3.],
[ 0., 4., 4., 4., 4.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.]],
[[ 0., 2., 2., 2., 2.],
[ 0., 3., 3., 3., 3.],
[ 0., 4., 4., 4., 4.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.]]])
IRtest = np.array([[[-0.07383495, -0.08606554, -0.08480594, -0.08099556, -0.08218414],
[-0.07866761, -0.08373 , -0.08253587, -0.08106102, -0.08220205],
[-0.07727436, -0.08271511, -0.0807254 , -0.07832416, -0.08021686],
[-0.07612349, -0.08190446, -0.07996929, -0.07842754, -0.08024891],
[-0.07488144, -0.08150557, -0.08038229, -0.07895656, -0.07997815]],
[[-0.07383495, -0.08606554, -0.08480594, -0.08099556, -0.08218414],
[-0.07866761, -0.08373 , -0.08253587, -0.08106102, -0.08220205],
[-0.07727436, -0.08271511, -0.0807254 , -0.07832416, -0.08021686],
[-0.07612349, -0.08190446, -0.07996929, -0.07842754, -0.08024891],
[-0.07488144, -0.08150557, -0.08038229, -0.07895656, -0.07997815]]])
因此预期的阵列看起来像:
array_expected = np.array([[[-0.08271511, -0.0807254 , -0.07832416, -0.08021686, 0],
[-0.08190446, -0.07996929, -0.07842754, -0.08024891, 0],
[-0.08150557, -0.08038229, -0.07895656, -0.07997815, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]],
[[-0.08271511, -0.0807254 , -0.07832416, -0.08021686, 0],
[-0.08190446, -0.07996929, -0.07842754, -0.08024891, 0],
[-0.08150557, -0.08038229, -0.07895656, -0.07997815, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]])
我试着用我上一篇文章得到的代码部分。
b = np.zeros_like(IRtest)
for i in range(IRtest.shape[1]):
for j in range(IRtest.shape[2]):
for k in range(IRtest.shape[0]):
b[k, j, i] = IRtest[k,my[k,j,i],mx[k,j,i]]*(mx[k,j,i]!=-1)*(my[k,j,i]!=-1)
b
但结果与我预期的结果不一样:
array([[[-0.08606554, -0.0807254 , -0.07832416, -0.08021686, -0.07727436],
[-0.08606554, -0.07996929, -0.07842754, -0.08024891, -0.07612349],
[-0.08606554, -0.08038229, -0.07895656, -0.07997815, -0.07488144],
[-0.08606554, -0.08480594, -0.08099556, -0.08218414, -0.07383495],
[-0.08606554, -0.08480594, -0.08099556, -0.08218414, -0.07383495]],
[[-0.08606554, -0.0807254 , -0.07832416, -0.08021686, -0.07727436],
[-0.08606554, -0.07996929, -0.07842754, -0.08024891, -0.07612349],
[-0.08606554, -0.08038229, -0.07895656, -0.07997815, -0.07488144],
[-0.08606554, -0.08480594, -0.08099556, -0.08218414, -0.07383495],
[-0.08606554, -0.08480594, -0.08099556, -0.08218414, -0.07383495]]])
你的地图矩阵是错误的,要得到你想要的结果就像这样(因为,当你把值放入b时,你正在检查m [k,j,i]!= -1并且你想要最后一列为0,而不是第一个)
mx = np.array([[[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.]],
[[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.],
[ 1., 2., 3., 4., -1.]]])
my = np.array([[[ 2., 2., 2., 2., -1.],
[ 3., 3., 3., 3., -1.],
[ 4., 4., 4., 4., -1.],
[ -1., -1., -1., -1., -1.],
[ -1., -1., -1., -1., -1.]],
[[ 2., 2., 2., 2., -1.],
[ 3., 3., 3., 3., -1.],
[ 4., 4., 4., 4., -1.],
[ -1., -1., -1., -1., -1.],
[ -1., -1., -1., -1., -1.]]])
同样在你的循环中,最好切换第一个和第二个循环中的尺寸,使它们变成
for i in range(IRtest.shape[2]):
for j in range(IRtest.shape[1]):
for k in range(IRtest.shape[0]):
这对于你在这里给出的情况无关紧要,因为矩阵是正方形的,但是你提到矩阵的真正问题不是正方形,因此它成为一个问题。
总结一下你之前关于2dim的问题的答案,你可以简单地使用花式索引(当然,在修复数组的dtypes之后):
b = IRtest[my,mx] * ~(mask_my | mask_mx)
现在,为了将相同的技术应用于3dim情况,您需要创建一个“中性”索引数组,以应用于第一个轴。 这是np.indices
有用的地方:
mz = np.indices(IRtest.shape)[0] # take [0] because we need to be neutral w.r.t. axis=0
现在应用花哨的索引:
b = IRtest[mz, my, mx]
要应用蒙版,最简单的方法是将一个维度添加到蒙版数组中以使其成为3dim,然后让numpy的广播发挥其魔力。 (我假设我们在2dim问题中使用相同的掩码,dtype = bool)。
unified_mask = mask_my | mask_mx
b *= ~unified_mask[np.newaxis,...]
与2dim情况一样,您可以同时使用花式分配(同样,轴= 0正在广播):
b[unified_mask[np.newaxis,...]] = 0.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.