6

I'm new to python, so I'm used to use array[i][j] instead of array[i,j]. Today a script I created following a tutorial was not working until I found out that I was using

numpy.dot(P[0][:], Q[:][0])

instead of

numpy.dot(P[0,:], Q[:,0])

For some reason the second one works, while the first one gives me a shape error. The matrixes dimensions are MxK and KxN.

I tried to print both P[0][:] and P[0,:], run id(), type() and P[0][:].shape, but couldn't find a reason to it. Why are these things different?

I'm running it on Jupyter Notebook 4.3.0 and Python 2.7.13.

2
  • You may want to read How to Ask and minimal reproducible example. Commented May 17, 2017 at 1:41
  • 3
    Try searching the difference between indexing and slicing Commented May 17, 2017 at 1:45

2 Answers 2

6

You should almost always use [i, j] instead of [i][j] when dealing with numpy arrays. In many cases there's no real difference but in your case there is.

Suppose you have an array like this:

>>> import numpy as np
>>> arr = np.arange(16).reshape(4, 4)
>>> arr 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

When you use [:] that's equivalent to a new view, but if you do [1, :] or [:, 1] it means get the second row (column). Roughly speaking it means: index the dimension where you had the number and leave the dimension where you had the : alone:

>>> arr[:]
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

>>> arr[:, 1]  #  get the second column
array([ 1,  5,  9, 13])
>>> arr[:][1]  # get a new view of the array, then get the second row
array([4, 5, 6, 7])

This is because [1] is interpreted as [1, ...] (... is the Ellipsis object) and for 2D it's equivalent to [1, :].

That's also the reason why the row indexing still works (because it's the first dimension):

>>> arr[1, :]  # get the second row
array([4, 5, 6, 7])
>>> arr[1][:]  # get the second row, then get a new view of that row
array([4, 5, 6, 7])
Sign up to request clarification or add additional context in comments.

1 Comment

[:] is a copy for a list,but not an array. It is rarely useful on the RHS with arrays
4

x[:] makes a shallow copy of a list, but is virtually useless when x is an array. It makes a new view - same data and shape, but different array object. If that's confusing you need to review some basic numpy docs about views and copies.

In a 2d array such as A[0,:] or A[:, 1:5], : is a kind of place holder, identifying a dimension that will be used as a whole. : is converted by Python interpreter to slice(None,None,None), while start:stop:step produces slice(start, stop, step).

A[0,:], which can be shortened to A[0], means pick the 1st 'row' of A, and all of its 'columns'. The action generalizes to higher dimensions, where names like row and column have less intuitive meanings.

A[:,0] means pick the 0th column, and all the row.

A[0][:] expands to A[0,:][:], and means apply [:] to the result of A[0,:], in effect, just take a view of the 1st row (which is a 1d array).

A[:][0] is not the same as A[:,0]; it's the same as A[0,:]. A[:] is the same as A[:,:] a view of the whole 2d array.

If it helps, I could expand the indexing expressions into calls to A.__getitem__(...). Each set of [] is a separate expansion.

In the expression A[:] = ... the [:] is significant, but that's another topic.


These 2 expressions are equivalent:

numpy.dot(P[0][:], Q[:][0])
numpy.dot(P[0,:], Q[0,:])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.