Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy: Why doesn't 'a += a.T' work?

Tags:

python

numpy

As stated in scipy lecture notes, this will not work as expected:

a = np.random.randint(0, 10, (1000, 1000))
a += a.T
assert np.allclose(a, a.T)

But why? How does being a view affect this behavior?

like image 807
AmirHossein Avatar asked Apr 22 '16 06:04

AmirHossein


People also ask

How do I fix No module named NumPy in Python?

The Python "ModuleNotFoundError: No module named 'numpy'" occurs when we forget to install the numpy module before importing it or install it in an incorrect environment. To solve the error, install the module by running the pip install numpy command.

Does NumPy only work with numbers?

The elements of a NumPy array, or simply an array, are usually numbers, but can also be boolians, strings, or other objects.


1 Answers

a += a.T

does in-place summing up (it's using view a.T while processing), so you end up with a non-symmetric matrix you can easily check this, i.e. I got:

In [3]: a
Out[3]: 
array([[ 6, 15,  7, ...,  8,  9,  2],
       [15,  6,  9, ..., 14,  9,  7],
       [ 7,  9,  0, ...,  9,  5,  8],
       ..., 
       [ 8, 23, 15, ...,  6,  4, 10],
       [18, 13,  8, ...,  4,  2,  6],
       [ 3,  9,  9, ..., 16,  8,  4]])

You can see it's not symmetric, right? (compare right-top and left-bottom items)

if you do a real copy:

a += np.array(a.T)

it works fine, i.e.:

In [6]: a
Out[6]: 
array([[ 2, 11,  8, ...,  9, 15,  5],
       [11,  4, 14, ..., 10,  3, 13],
       [ 8, 14, 14, ..., 10,  9,  3],
       ..., 
       [ 9, 10, 10, ..., 16,  7,  6],
       [15,  3,  9, ...,  7, 14,  1],
       [ 5, 13,  3, ...,  6,  1,  2]])

To better understand why it does so, you can imagine you wrote the loop yourself as following:

In [8]: for i in xrange(1000):
            for j in xrange(1000):
                a[j,i] += a[i,j]
   ....:         

In [9]: a
Out[9]: 
array([[ 4,  5, 14, ..., 12, 16, 13],
       [ 3,  2, 16, ..., 16,  8,  8],
       [ 9, 12, 10, ...,  7,  7, 23],
       ..., 
       [ 8, 10,  6, ..., 14, 13, 23],
       [10,  4,  6, ...,  9, 16, 21],
       [11,  8, 14, ..., 16, 12, 12]])

It adds a[999,0] to calculate a[0,999] but a[999,0] already has sum of a[999,0] + a[0,999] -- so below the main diagonal you add the values twice.

like image 111
Yuri Baburov Avatar answered Oct 09 '22 07:10

Yuri Baburov