[英]Replacing 2D subarray in 3D array if condition is met
I have a matrix that looks like this:我有一个看起来像这样的矩阵:
a = np.random.rand(3, 3, 3)
[[[0.04331462, 0.30333583, 0.37462236],
[0.30225757, 0.35859228, 0.57845153],
[0.49995805, 0.3539933, 0.11172398]],
[[0.28983508, 0.31122743, 0.67818926],
[0.42720309, 0.24416101, 0.5469823 ],
[0.22894097, 0.76159389, 0.80416832]],
[[0.25661154, 0.64389696, 0.37555374],
[0.87871659, 0.27806621, 0.3486518 ],
[0.26388296, 0.8993144, 0.7857116 ]]]
I want to check every block for a value smaller than 0.2.我想检查每个块的值是否小于 0.2。 If value is smaller than 0.2 then the whole block equals 0.2.如果值小于 0.2,则整个块等于 0.2。 In this case:在这种情况下:
[[[0.2 0.2 0.2]
[0.2 0.2 0.2]
[0.2 0.2 0.2]]
[[0.28983508 0.31122743 0.67818926]
[0.42720309 0.24416101 0.5469823 ]
[0.22894097 0.76159389 0.80416832]]
[[0.25661154 0.64389696 0.37555374]
[0.87871659 0.27806621 0.3486518 ]
[0.26388296 0.8993144 0.7857116 ]]]
Here is a vectorized way to get what you want.这是获得所需内容的矢量化方式。
Taking a
from your example:以a
从你的例子:
a[(a < 0.2).any(axis=1).any(axis=1)] = 0.2
print(a)
gives:给出:
array([[[ 0.2 , 0.2 , 0.2 ],
[ 0.2 , 0.2 , 0.2 ],
[ 0.2 , 0.2 , 0.2 ]],
[[ 0.28983508, 0.31122743, 0.67818926],
[ 0.42720309, 0.24416101, 0.5469823 ],
[ 0.22894097, 0.76159389, 0.80416832]],
[[ 0.25661154, 0.64389696, 0.37555374],
[ 0.87871659, 0.27806621, 0.3486518 ],
[ 0.26388296, 0.8993144 , 0.7857116 ]]])
Explanation:解释:
Taking another example where each step will be more clear:再举一个例子,其中每一步都会更加清晰:
a = np.array([[[0.51442898, 0.90447442, 0.45082496],
[0.59301203, 0.30025497, 0.43517362],
[0.28300437, 0.64143037, 0.73974422]],
[[0.228676 , 0.59093859, 0.14441217],
[0.37169639, 0.57230533, 0.81976775],
[0.95988687, 0.43372407, 0.77616701]],
[[0.03098771, 0.80023031, 0.89061113],
[0.86998351, 0.39619143, 0.16036088],
[0.24938437, 0.79131954, 0.38140462]]])
Let's see which elements are less than 0.2:让我们看看哪些元素小于 0.2:
print(a < 0.2)
gives:给出:
array([[[False, False, False],
[False, False, False],
[False, False, False]],
[[False, False, True],
[False, False, False],
[False, False, False]],
[[ True, False, False],
[False, False, True],
[False, False, False]]])
From here we would like to get indices of those 2D arrays that have at least one True
element: [False, True, True]
.从这里我们想得到那些至少有一个True
元素的二维数组的索引: [False, True, True]
。 We require np.any
for this. np.any
,我们需要np.any
。 Note that I will be using np.ndarray.any
method chaining here instead of nesting function calls of np.any
.请注意,我将在这里使用np.ndarray.any
方法链接,而不是嵌套np.any
函数调用。 1 1
Now just using (a < 0.2).any()
will give just True
because by default it performs logical OR over all dimensions.现在只使用(a < 0.2).any()
将给出True
因为默认情况下它在所有维度上执行逻辑或。 We have to specify axis
parameter.我们必须指定axis
参数。 In our case we will be fine with either axis=1
or axis=2
.在我们的例子中,我们可以使用axis=1
或axis=2
。 2 2
print((a < 0.2).any(axis=1))
gives 3 :给出3 :
array([[False, False, False],
[False, False, True],
[ True, False, True]])
From here we get desired boolean indices by applying another .any()
along the rows:从这里我们通过沿行应用另一个.any()
来获得所需的布尔索引:
print((a < 0.2).any(axis=1).any(axis=1))
gives:给出:
array([False, True, True])
Fianlly, we can simply use this boolean index array to replace the values of the original array:最后,我们可以简单地使用这个布尔索引数组来替换原始数组的值:
a[(a < 0.2).any(axis=1).any(axis=1)] = 0.2
print(a)
gives:给出:
array([[[0.51442898, 0.90447442, 0.45082496],
[0.59301203, 0.30025497, 0.43517362],
[0.28300437, 0.64143037, 0.73974422]],
[[0.2 , 0.2 , 0.2 ],
[0.2 , 0.2 , 0.2 ],
[0.2 , 0.2 , 0.2 ]],
[[0.2 , 0.2 , 0.2 ],
[0.2 , 0.2 , 0.2 ],
[0.2 , 0.2 , 0.2 ]]])
1 Just compare chaining: 1只是比较链接:
a[(a < 0.2).any(axis=1).any(axis=1)] = 0.2
with nesting:带嵌套:
a[np.any(np.any(a < 0.2, axis=1), axis=1)] = 0.2
I think the latter is more confusing.我认为后者更令人困惑。
2 For me this was difficult to comprehend at first. 2对我来说,这起初很难理解。 What helped me was to draw an image of a 3x3x3 cube, print results for different axis, and check which axis correspond to which directions.帮助我的是绘制一个 3x3x3 立方体的图像,打印不同轴的结果,并检查哪个轴对应哪个方向。 Also, here is an explanation of using axis with np.sum
in 3D case: Axis in numpy multidimensional array.此外,这里是在 3D 情况下使用带有np.sum
轴的说明: numpy 多维数组中的轴。
3 One could expect to get [False, True, True]
at once which is not the case. 3人们可能期望立即得到[False, True, True]
,但事实并非如此。 For explanation see this: Small clarification needed on numpy.any for matrices有关解释,请参阅: 矩阵的 numpy.any 上的小说明
Since you have three layer to your matrix, try this (having your matrix being a):因为你的矩阵有三层,试试这个(让你的矩阵是 a):
for x in a:
for y in x:
for z in y:
if z < 0.2:
z=0.2
for i, block in enumerate(a):
if (block < 0.2).flatten().any():
a[i] = np.ones(np.shape(block)) * 0.2
print(a)
array([[[ 0.2 , 0.2 , 0.2 ],
[ 0.2 , 0.2 , 0.2 ],
[ 0.2 , 0.2 , 0.2 ]],
[[ 0.28983508, 0.31122743, 0.67818926],
[ 0.42720309, 0.24416101, 0.5469823 ],
[ 0.22894097, 0.76159389, 0.80416832]],
[[ 0.25661154, 0.64389696, 0.37555374],
[ 0.87871659, 0.27806621, 0.3486518 ],
[ 0.26388296, 0.8993144 , 0.7857116 ]]])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.