简体   繁体   English

在 numpy 零数组中分配元素

[英]Assigning elements in a numpy array of zeros

I am trying to draw a "one" on a numpy array np.zeros((28, 28)) by assigning certain rows and columns to 255. I have written the following code:我试图通过将某些行和列分配给 255 来在 numpy 数组np.zeros((28, 28))上绘制一个“一”。我编写了以下代码:

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

The output I'm getting after this is a simple array of zeros with no changes.在此之后我得到的输出是一个简单的零数组,没有任何变化。 Can anyone please explain this strange behavior?谁能解释一下这种奇怪的行为?

Bonus奖金

If you interchange [12:15] and [5:23] , rows 17 to 19 are filled with 255.如果交换[12:15][5:23] ,第 17 到 19 行将填充为 255。

With one[12:15][5:23] you first select rows from 12 to 15 (3 rows), then you select rows 5 to 23 from these 3 rows.使用one[12:15][5:23]首先从 12 到 15(3 行)中选择行,然后从这 3 行中选择第 5 到 23 行。 These rows do not exists, then you do not update anything.这些行不存在,那么您不更新任何内容。

The syntax for updating rows 12 to 15 crossed with columns 5 to 23 is更新第 12 到 15 行与第 5 到 23 列交叉的语法是

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

The notation you are using is valid but does something very different from what you expect.您使用的符号是有效的,但与您期望的完全不同。 Numpy indices consist of tuples, one element per dimension. Numpy 索引由元组组成,每个维度一个元素。 The index you are trying to get looks like this您尝试获取的索引如下所示

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

For convenience, python allows you to remove the parentheses, so almost everyone would write为了方便,python允许去掉括号,所以几乎每个人都会写

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

It's useful to remember that that's just shorthand for a tuple containing slice objects, because sometimes you have to build it externally.记住这只是包含切片对象的元组的简写很有用,因为有时您必须在外部构建它。

Let's look at what your original index actually does.让我们看看您的原始索引实际上做了什么。 Each bracket expression in python is a call to __getitem__ or __setitem__ . python 中的每个括号表达式都是对__getitem____setitem__的调用。 Your index can be rewritten as您的索引可以重写为

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

You are allowed to pass in a tuple that is shorter than the number of dimensions.您可以传入一个比维数短的元组。 In that case, the leading dimensions are indexed, and all the remaining dimensions are implicit grabbed in their entirety.在这种情况下,主要维度被索引,所有剩余的维度都被隐式地整体抓取。 What that means practically is that you are effectively doing这实际上意味着你正在有效地做

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

view is a slice of rows 12-14, inclusive. view是第 12-14 行(包括第 12-14 行)的切片。 It is a 3x28 array.它是一个 3x28 数组。 In keeping with python convention, numpy allows you to assign to indices past the end of an array, silently doing nothing.与 python 约定保持一致,numpy 允许您分配数组末尾的索引,静默地什么都不做。 view has only 3 rows, so assigning rows 5-22 does nothing. view只有 3 行,因此分配第 5-22 行没有任何作用。

Hopefully this makes the situation in your edit clear.希望这可以使您编辑中的情况清楚。 If you grab rows 5-22, you get an 18x28 slice of ones , offset by 5 rows.如果你抢行5-22,你会得到一个18x28片的ones ,由5行偏移。 This slice has rows 12-14, so you end up setting rows 12+5, 13+5 and 14+5 in the original array.这个切片有 12-14 行,所以你最终在原始数组中设置了 12+5、13+5 和 14+5 行。

To expand on jpl's answer: your syntax would be correct if you were dealing with python's list data structure.扩展 jpl 的答案:如果您正在处理 python 的列表数据结构,您的语法将是正确的。 But you are dealing with numpy's ndarray data structure so it is not and jpl syntax is correct.但是您正在处理 numpy 的 ndarray 数据结构,因此它不是并且 jpl 语法是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM