Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy - weird behavior with plus equal with slicing

Tags:

python

numpy

Plus equal is giving a different answer than assigning to the explicit sum (which is the answer one expects), when slicing is involved. Is there a reason for this? Should plus equal be avoided?

a = np.arange(10)
b = np.arange(10)
a[3:] += a[:-3]
b[3:] = b[3:] + b[:-3]
print a
#[ 0  1  2  3  5  7  9 12 15 18] 
print b
#[ 0  1  2  3  5  7  9 11 13 15]
like image 231
brasqueychutter Avatar asked Oct 17 '13 03:10

brasqueychutter


People also ask

Can NumPy arrays be jagged?

NumPy does not support jagged arrays natively.

How does NumPy array slicing work?

Numpy with Python Basic slicing is an extension of Python's basic concept of slicing to n dimensions. A Python slice object is constructed by giving start, stop, and step parameters to the built-in slice function. This slice object is passed to the array to extract a part of array.

Why NumPy array operations are faster than looping?

NumPy Arrays are faster than Python Lists because of the following reasons: An array is a collection of homogeneous data-types that are stored in contiguous memory locations. On the other hand, a list in Python is a collection of heterogeneous data types stored in non-contiguous memory locations.

Is NumPy always faster than list?

As predicted, we can see that NumPy arrays are significantly faster than lists.


1 Answers

As JBernardo commented, += change the array in place.

a[3:] += [a:-3] is similar to following:

>>> import numpy as np
>>> a = np.arange(10)
>>> 
>>> for i in range(3, 10):
...     print('a[{}] ({}) += a[{}] ({})'.format(i, a[i], i-3, a[i-3]))
...     a[i] += a[i-3]
...     print('  a[{}] -> {}'.format(i, a[i]))
... 
a[3] (3) += a[0] (0)
  a[3] -> 3
a[4] (4) += a[1] (1)
  a[4] -> 5
a[5] (5) += a[2] (2)
  a[5] -> 7
a[6] (6) += a[3] (3)
  a[6] -> 9
a[7] (7) += a[4] (5)  # NOTE: not (4)
  a[7] -> 12
a[8] (8) += a[5] (7)
  a[8] -> 15
a[9] (9) += a[6] (9)
  a[9] -> 18

To avoid that, use copy of the array:

>>> a = np.arange(10)
>>> a[3:] += np.copy(a[:-3]) # OR np.array(a[:-3])
>>> a
array([ 0,  1,  2,  3,  5,  7,  9, 11, 13, 15])
like image 68
falsetru Avatar answered Oct 23 '22 19:10

falsetru