[Numpy-discussion] Can not update a submatrix

Anne Archibald peridot.faceted@gmail....
Wed Jan 30 13:43:06 CST 2008


On 30/01/2008, Francesc Altet <faltet@carabos.com> wrote:
> A Wednesday 30 January 2008, Nadav Horesh escrigué:
> > In the following piece of code:
> > >>> import numpy as N
> > >>> R = N.arange(9).reshape(3,3)
> > >>> ax = [1,2]
> > >>> R
> >
> > array([[0, 1, 2],
> >        [3, 4, 5],
> >        [6, 7, 8]])
> >
> > >>> R[ax,:][:,ax] = 100
> > >>> R
> >
> > array([[0, 1, 2],
> >        [3, 4, 5],
> >        [6, 7, 8]])
> >
> > Why R is not updated?
>
> Because R[ax] is not a view of R, but another copy of the original
> object (fancy indexing does return references to different objects).
> In order to get views, you must specify only a slice of the original
> array.  For example:

This is not exactly correct.

There are two kinds of fancy indexing in numpy, which behave
similarly. There is normal fancy indexing, which produces a new array,
not sharing data with the old array:

a = N.random.normal(size=10)
b = a[a>0]

There is also fancy indexing of lvalues (to use a C term):

a = N.random.normal(size=10)
a[a<0] *= -1

Here no copy is made; instead, the data is modified in-place. This
requires some clever hacks under the hood, since a[a<0] *can't* be a
view of a.

The problem the OP had is that they are going beyond what the clever
hacks can deal with. That's why

R[ax,:] = 100

works but

R[ax,:][:,ax] = 100

doesn't. The problem is that you have two indexing operations in the
second situation, and the inplace operators can't deal with that.

Solutions include working on a flattened version of the array (for
which a single indexing operation suffices), using the (not in-place)
where() construct, or using the ix_ function:

R[N.ix_(ax,ax)] = 100

N.ix_ is necessary because R[ax,ax] doesn't do what I, for one, would
have expected: R[[1,2],[3,4]] yields [R[1,3],R[2,4]], not
[[R[1,3],R[1,4]],[R[2,3],R[2,4]]]. But in any case, once you reduce it
to a single fancy-indexing operation, you can successfully use it as
an lvalue. Striding and views are not really the issue.

Anne


More information about the Numpy-discussion mailing list