python - Python多维数组索引说明

标签 python numpy multidimensional-array indexing numpy-ndarray

有人可以告诉我这里发生了什么吗?我了解这里发生的事情: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),其中elemt的每个元素。结果将是另一个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(因为xx[t]的第二维的长度)。回顾一下,我们推断出x[t,:]的结果形状将是(3,3,3)的结果形状,而该结果形状又将是x[t]。这意味着x将是一个三维数组,即使(3,3,3)本身只是一个二维数组。

请注意,在结果的形状3中,前两个t由高级索引3贡献,最后一个:由隐式基本索引t贡献。这两个索引:3,3也使用不同的方式得出各自的贡献。来自索引tt贡献只是t本身的形状。它不在乎索引中x[t,:]在表达式t中的位置(它不在乎:是在:之前出现还是t3之前出现)。来自索引: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生成的索引值为12x
我们仅指的是x[t, :]中与这些索引值的组合相对应的位置。也就是说,x[i,j]仅与那些位置i有关,其中0采用值1j,而0采用值12x[t, :]。即,x[0,0]仅与数组x[0,1]中的位置x[0,2]x[1,0]x[1,1]x[1,2]xx[t, :] = 0有关。
因此,赋值语句x0中的这些位置赋值为0。实际上,我们将值x分配给x的前两行中的所有三列,而将x的第三行保持不变。


第10行:

在上述分配后打印的值。

关于python - Python多维数组索引说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54661057/

相关文章:

python - python中的正则表达式操作

python - 属性错误 : str has no attribute remove

python - Numpy:根据数组索引设置每一列的一个特定元素

numpy - 为什么我不能将数据分配给第一个 "try:"中的稀疏矩阵的一部分?

php - 从 php select 创建多维数组

c - 从文件中读取 float

python - numpy: "array_like"对象的正式定义?

python - python 中的冒号放在数组后面有什么作用?

python - 使用 Pandas 滚动相关时如何处理不一致的结果?

c - 如何重新分配不同大小的二维结构指针