Assigning elements in a numpy array of zeros

给你一囗甜甜゛ 提交于 2021-02-10 14:51:08

问题


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:

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.


回答1:


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. 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

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__. 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. It is a 3x28 array. In keeping with python convention, numpy allows you to assign to indices past the end of an array, silently doing nothing. view has only 3 rows, so assigning rows 5-22 does nothing.

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. This slice has rows 12-14, so you end up setting rows 12+5, 13+5 and 14+5 in the original array.




回答2:


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. 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

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



回答3:


To expand on jpl's answer: your syntax would be correct if you were dealing with python's list data structure. But you are dealing with numpy's ndarray data structure so it is not and jpl syntax is correct.



来源:https://stackoverflow.com/questions/60918089/assigning-elements-in-a-numpy-array-of-zeros

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!