Lesson 2 of 7

Views, copies and memory layout

Most ways of indexing an array hand you a second name for the same memory. Some hand you new memory. They look identical, and writing to the wrong one is a bug that raises nothing.

An array is a buffer, a shape, a dtype and a strides tuple. Almost everything you can do to one changes the last three and leaves the buffer alone -- which is why slicing and transposing are free, and why they can quietly edit data you thought you had copied.

Six ideas, and one question underneath all of them: does this touch the original, or a copy of it?

Every board asks the same question in a different costume: does this touch the original, or a copy of it? Nothing runs — the answers come from the rules about how NumPy indexes, which is what you are here to learn.

1 of 6

A slice is a window, not a photograph

Most indexing hands you a second name for the same memory. Some of it hands you new memory. The two look identical.

Slice a Python list and you get a new list. Slice an array and, most of the time, you get a view: a second array object pointing at the same buffer. Nothing was copied. Both names refer to one block of memory.

The dividing line is not arbitrary. Basic slicing can always be described as "start here, then step this far each time", and that description is all an array is, so NumPy hands you a new description of the same bytes:

a[1:3]        view      evenly spaced
a[:, 0]       view      evenly spaced
a.T           view      just a different description
a.reshape(6)  view      usually

Fancy indexing and boolean masks pick elements that are not evenly spaced. There is no start-and-step that describes them, so NumPy has no choice but to gather them into a new buffer:

a[[0, 2]]     copy      arbitrary positions
a[a > 2]      copy      arbitrary positions
a.copy()      copy      you asked
a + 1         copy      a new array of results

Both come back as an array and print the same way. Nothing in the output tells you which one you are holding.

a.base is the tell. On a view it points at the array the memory belongs to; on a fresh array it is None. It is the only way to ask the question directly.

Challenge

View or Copy?

1 of 8

Say which one you are holding.

Evenly spaced elements can be described by a start and a step, so NumPy hands back a window. Anything else has to be gathered into new memory.