在由零组成的numpy数组中分配元素



我正试图通过将某些行和列分配给255来在numpy数组np.zeros((28, 28))上画一个"一"。我已经写了以下代码:

one = np.zeros((28, 28))
one[12:15][5:23] = 255

在这之后,我得到的输出是一个简单的零数组,没有任何变化。有人能解释一下这种奇怪的行为吗?

奖金

如果交换[12:15][5:23],则第17到19行将填充255。

使用one[12:15][5:23],首先从12到15行(3行(中选择行,然后从这3行中选择第5到23行。这些行不存在,则不更新任何内容。

用于更新与列5至23交叉的行12至15的语法是

one[12:15,5:23] = 255

您正在使用的表示法是有效的,但所做的与您期望的非常不同。Numpy索引由元组组成,每个维度一个元素。你试图得到的索引看起来像这个

one[(12:15, 5:23)] = 255

为了方便起见,python允许您删除括号,所以几乎每个人都会编写

one[12:15, 5:23] = 255

记住这只是包含切片对象的元组的简写,这很有用,因为有时您必须从外部构建它。

让我们看看您的原始索引实际起到了什么作用。python中的每个括号表达式都是对__getitem____setitem__的调用。您的索引可以重写为

view = one[12:15]  # __getitem__
view[5:23] = 255   # __setitem__

允许传入一个短于维度数的元组。在这种情况下,前面的维度被索引,所有剩余的维度都被隐式地整体抓取。这实际上意味着你正在有效地进行

view = one[12:15, :]
view[5:23, :] = 255

view是包括第12-14行的一个切片。它是一个3x28阵列。根据python惯例,numpy允许您为超过数组末尾的索引赋值,而无需执行任何操作。view只有3行,所以分配第5-22行没有任何作用。

希望这能让你的编辑中的情况变得清楚。如果获取第5-22行,则会得到一个18x28的ones切片,偏移5行。这个切片有12-14行,所以最终在原始数组中设置了12+5、13+5和14+5行。

扩展jpl的答案:如果您处理python的列表数据结构,您的语法将是正确的。但您正在处理numpy的ndarray数据结构,所以它不是,jpl语法是正确的。

最新更新