有人可以告诉我这里发生了什么吗?我了解这里发生的事情:https://docs.scipy.org/doc/numpy-1.15.0/user/basics.indexing.html#index-arrays,但是不了解这段代码。
import numpy as np
y = np.zeros((3,3))
y = y.astype(np.int16)
y[1,1] = 1
x = np.ones((3,3))
t = (1-y).astype(np.int16)
print(t)
print(x[t])
x[(1-y).astype(np.int16)] = 0
print(x)
输出:
[[1 1 1]
[1 0 1]
[1 1 1]]
[[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]]
[[0. 0. 0.]
[0. 0. 0.]
[1. 1. 1.]]
最佳答案
import numpy as np # Line 01
y = np.zeros((3,3)) # Line 02
y = y.astype(np.int16) # Line 03
y[1,1] = 1 # Line 04
x = np.ones((3,3)) # Line 05
t = (1-y).astype(np.int16) # Line 06
print(t) # Line 07
print(x[t]) # Line 08
x[(1-y).astype(np.int16)] = 0 # Line 09
print(x) # Line 10
第02行:
创建零的二维3 x 3 ndarray。
y
是指向该ndarray的名称。03行:
将
y
的每个元素的数据类型设置为16位整数。04行:
将中间行和中间列的交点处的
y
元素设置为1
。05行:
创建一个二维的3 x 3 ndarray。
x
是指向该ndarray的名称。第06行:
减法(
1-t
)导致多个标量减法(1- elem
),其中elem
是t
的每个元素。结果将是另一个ndarray,其形状与t
相同,并且将减法(1- elem
)的结果作为其值。也就是说,ndarray (1-t)
的值将为:[[1-t[0,0], 1-t[0,1], 1-t[0,2]],
[1-t[1,0], 1-t[1,1], 1-t[1,2]],
[1-t[2,0], 1-t[2,1], 1-t[2,2]]]
由于
t
充满零,并且在中间行和中间列的交点处有一个单独的1
,因此(1-t)
将是一个由1组成的二维ndarray,在0
的交点处有一个t
中间行和中间列。第07行:
打印
x
第08行:
从这里开始,事情变得有些棘手。这里发生的事情称为“高级索引和基本索引组合”(https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html#combining-advanced-and-basic-indexing)。让我们逐步详细介绍。
首先,请注意
t
是二维ndarray,以另一个整数ndarray x
作为索引。由于t
需要提供两个索引,因此:
将被视为这两个索引中的第一个,而第二个索引将被隐式假定为x[t]
。因此,x[t,:]
首先被解释为t
。这两个索引的存在(其中一个索引是整数:
的数组,而另一个索引是切片t
)导致出现这种情况,称为“组合式高级索引和基本索引”。现在,在这种“组合”方案中究竟发生了什么?开始:
首先,结果的形状将来自第一个索引
:
和第二个索引t
的贡献。现在,(3,3)
具有形状t
,因此x[t,:]
对(3,3,)
结果形状的贡献是提供结果形状的最外部(最左侧)尺寸。因此,结果形状将以:
开头。现在,x[t,:]
对x
形状的贡献基于以下问题的答案::
在哪个:
维度上应用?答案是-第二维(因为x[t,:]
是:
中的第二个索引)。因此,x[t,:]
对3
的结果形状的贡献为3
(因为x
是x[t]
的第二维的长度)。回顾一下,我们推断出x[t,:]
的结果形状将是(3,3,3)
的结果形状,而该结果形状又将是x[t]
。这意味着x
将是一个三维数组,即使(3,3,3)
本身只是一个二维数组。请注意,在结果的形状
3
中,前两个t
由高级索引3
贡献,最后一个:
由隐式基本索引t
贡献。这两个索引:
和3,3
也使用不同的方式得出各自的贡献。来自索引t
的t
贡献只是t
本身的形状。它不在乎索引中x[t,:]
在表达式t
中的位置(它不在乎:
是在:
之前出现还是t
在3
之前出现)。来自索引:
的x
贡献是x
的第二维度的长度,我们考虑:
的第二维度,因为x[t,:]
是表达式x
中的第二个索引。如果(3,5)
的形状为(3,3)
而不是x[t,:]
,则(3,3,5)
的形状应为(3,3,3)
而不是x[t]
。现在我们已经推导了
(3,3,3)
结果的形状为t
,让我们继续了解值本身如何确定结果。结果中的值显然是位置[0,0,0]处的值,[0,0,1],[0,1,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0 ,2,1],[0,2,2],依此类推。让我们来看一个这些职位的例子,希望您能有所作为。对于我们的示例,让我们看一下结果中的位置[0,1,2]。为了获得该位置的值,我们将首先使用0和1索引到
t[0,1]
数组中。也就是说,我们找到1
,它将是print(t)
(请参阅1
的输出) )。在t[0,1]
获得的x
将被视为我们进入x
的第一个索引。 2
的第二个索引将是[0,1,2]
(请记住,我们正在讨论结果中的位置x
,并试图确定该位置的值)。现在,给定这些x
的第一个和第二个索引,我们从[0,1,2]
获得要填充到x[t]
的位置x
的值。现在,
x[t]
充满了。因此,即使x[t]
的形状为(3,3,3)
,x
也将仅包含一个。要真正测试您对我到目前为止所说的内容的理解,您需要用不同的值填充print(x[t])
:因此,暂时将第05行注释掉,并在其下面添加以下行:
x = np.arange(9).reshape((3,3)) # New version of Line 05
现在,您会发现第08行的
x[t]
为您提供:[[[3 4 5]
[3 4 5]
[3 4 5]]
[[3 4 5]
[0 1 2]
[3 4 5]]
[[3 4 5]
[3 4 5]
[3 4 5]]]
根据此输出,测试您对我上面所描述的内容的了解,以及如何确定结果中的值。 (也就是说,如果您了解了
print (x[t])
的上述说明,则应该能够为t
手动重建与上述相同的输出。第09行:
给定第06行的
x[t]
定义,第09行等效于x[t, :] = 0
,正如我们在上面看到的那样,等效于x[t, :] = 0
。分配
x[0:2, :] = 0
的效果与x[t, :]
的效果相同。为什么会这样呢?仅仅因为在
t
中:索引
0
生成的索引值为1
s和t
(因为0
是仅由1
s和:
s组成的整数索引数组)索引
0
生成的索引值为1
,2
和x
。我们仅指的是
x[t, :]
中与这些索引值的组合相对应的位置。也就是说,x[i,j]
仅与那些位置i
有关,其中0
采用值1
或j
,而0
采用值1
,2
或x[t, :]
。即,x[0,0]
仅与数组x[0,1]
中的位置x[0,2]
,x[1,0]
,x[1,1]
,x[1,2]
,x
,x[t, :] = 0
有关。因此,赋值语句
x
在0
中的这些位置赋值为0。实际上,我们将值x
分配给x
的前两行中的所有三列,而将x
的第三行保持不变。第10行:
在上述分配后打印
关于python - Python多维数组索引说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54661057/