Slicing a NumPy Array in a Loop

I need a good explanation (link) to explain NumPy slicing inside (for) loops. I have three cases.

def example1(array): for row in array: row = row + 1 return array def example2(array): for row in array: row += 1 return array def example3(array): for row in array: row[:] = row + 1 return array 

Simple case:

 ex1 = np.arange(9).reshape(3, 3) ex2 = ex1.copy() ex3 = ex1.copy() 

returns:

 >>> example1(ex1) array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> example2(ex2) array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> example3(ex3) array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 

You can see that the first result is different from the second and third.

+6
source share
2 answers

First example:

You extract the row and add 1 to it. Then you redefine the pointer row , but not the one that contains array ! Thus, this will not affect the original array.

Second example:

You are doing the operation in place - obviously, this will affect the original array if it is an array.

If you were doing a double loop, it would no longer work:

 def example4(array): for row in array: for column in row: column += 1 return array example4(np.arange(9).reshape(3,3)) array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) 

this does not work because you are not calling np.ndarray __iadd__ (to change the data pointed to by the array), but python int __iadd__ . So this example only works because your strings are numpy arrays.

Third example:

row[:] = row + 1 this is interpreted as something like row[0] = row[0]+1, row[1] = row[1]+1, ... again, it works in place, so it affects to the original array.

Bottom line

If you work with mutable objects like list or np.ndarray , you need to be careful what you change. Such an object has only points where the actual data is stored in memory, so changing this pointer ( example1 ) does not affect stored data. You need to follow the pointer (either directly using [:] ( example3 ) or indirectly using array.__iadd__ ( example2 )) to modify the stored data.

+4
source

In the first code, you are not doing anything with the new computed string; you retype the name row , and there is no longer a connection to the array.

In the second and third, you do not reinstall, but assign values ​​to the old variable. C += some internal function is called, which changes depending on the type of object that you allow it to act on. See the links below.

If you write row + 1 on the right side, a new array is computed. In the first case, you tell python to give it the name row (and forget the original object that used to be called row ). And in the third, the new array is written to the slice of the old row .

For further reading, follow the comment link to the question by @Thiru above. Or read about assignment and rewriting in general ...

+3
source

All Articles