NumArray array-indexing

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michael Drumheller

    NumArray array-indexing

    (If you're not interested in NumArray, please skip this message.)

    I am new to NumArray and I wonder if someone can help me with
    array-indexing. Here's the basic situation: Given a rank-2 array
    (i.e., a matrix) it seems to be trivial, with array indexing,
    to extract a subset of its *columns*. But it does not seem
    to be trivial to extract a subset of its *rows*. The code
    snippet below describes the problem (if it really is a problem)
    in detail. Note that the "problem" has an obvious, quick
    solution via take(), but I wish it could be done with
    the much more compact method of array indexing. I hope
    my little snippet conveys what I'm after.

    Basically, it seems to me that NumArray simply does not support
    the distinction between a column vector and a row vector. That
    is, if you have x=[1,2,3], then transpose(x) is a no-op. True?
    (Note that doing x.shape=[3,1] does not do what I want; it produces
    an awkward object that does not have the desired effect from
    an array-indexing point of view.) Does this strike anyone
    else as a rather serious limitation for someone (like me)
    who would love to use Python/NumArray for my daily math
    instead of, say, Matlab?

    Thank you.

    Mike D.

    -----------------------cut here-----------------------------

    Demo snippet:

    from numarray import *
    x = array(range(1,1 0), type=None, shape=[3,3])
    print "(A) Original 3x3 array:\n", x
    i = [1,2]
    print "(B) An index set:\n", i
    print "(C) 2nd and 3rd rows of x w/ take(x, i, 0):\n", take(x, i, 0)
    print "(D) 2nd and 3rd cols of x w/ take(x, i, 1):\n", take(x, i, 1)
    print "(E) 2nd and 3rd rows of x w/ x[i]:\n", x[i]
    print "(F) 2nd and 3rd rows of x w/ transpose(trans pose(x)[i]):\n",
    transpose(trans pose(x)[i])
    print "(G) Wish x[transpose(i)] would work, but alas:\n",
    x[transpose(i)]

    It has this output:

    (A) Original 3x3 array:
    [[1 2 3]
    [4 5 6]
    [7 8 9]]
    (B) An index set:
    [1, 2]
    (C) 2nd and 3rd rows of x w/ take(x, i, 0):
    [[4 5 6]
    [7 8 9]]
    (D) 2nd and 3rd cols of x w/ take(x, i, 1):
    [[2 3]
    [5 6]
    [8 9]]
    (E) 2nd and 3rd rows of x w/ x[i]:
    [[4 5 6]
    [7 8 9]]
    (F) 2nd and 3rd rows of x w/ transpose(trans pose(x)[i]):
    [[2 3]
    [5 6]
    [8 9]]
    (G) Wish x[transpose(i)] would work, but alas:
    [[4 5 6]
    [7 8 9]]
  • Christopher T King

    #2
    Re: NumArray array-indexing

    On 12 Aug 2004, Michael Drumheller wrote:
    [color=blue]
    > I am new to NumArray and I wonder if someone can help me with
    > array-indexing. Here's the basic situation: Given a rank-2 array
    > (i.e., a matrix) it seems to be trivial, with array indexing,
    > to extract a subset of its *columns*. But it does not seem
    > to be trivial to extract a subset of its *rows*.[/color]

    You can do this using slices, like so:
    [color=blue][color=green][color=darkred]
    >>> from numarray import *
    >>> a = array([[1, 2], [3, 4]])
    >>> a[:,1][/color][/color][/color]
    array([2, 4])

    ':' means 'take all values along this axis', just like how with standard
    Python lists it means 'take all values in the list'.
    [color=blue]
    > Basically, it seems to me that NumArray simply does not support
    > the distinction between a column vector and a row vector. That
    > is, if you have x=[1,2,3], then transpose(x) is a no-op. True?[/color]

    False. You have to supply numarray with a two-dimensional array in order
    to perform a two-dimensional transpose:
    [color=blue][color=green][color=darkred]
    >>> transpose([[1, 2, 3]])[/color][/color][/color]
    array([[1],
    [2],
    [3]])

    Comment

    • Christopher T King

      #3
      Re: NumArray array-indexing

      On Thu, 12 Aug 2004, Christopher T King wrote:
      [color=blue]
      > On 12 Aug 2004, Michael Drumheller wrote:
      >[color=green]
      > > Basically, it seems to me that NumArray simply does not support
      > > the distinction between a column vector and a row vector. That
      > > is, if you have x=[1,2,3], then transpose(x) is a no-op. True?[/color]
      >
      > False. You have to supply numarray with a two-dimensional array in order
      > to perform a two-dimensional transpose:[/color]

      Where by "False" I meant "The first sentence is false, but the second
      sentence is true". Column vectors and row vectors must be represented as
      two-dimensional arrays; transpose() of a one-dimensional array is a no-op
      since all transpose() does (by default) is reverse the order of the axes.

      Comment

      • Michael Drumheller

        #4
        Re: NumArray array-indexing

        Christopher T King <squirrel@WPI.E DU> wrote in message news:<Pine.LNX. 4.44.0408121433 170.9323-100000@ccc8.wpi .edu>...[color=blue]
        > On 12 Aug 2004, Michael Drumheller wrote:
        >[color=green]
        > > I am new to NumArray and I wonder if someone can help me with
        > > array-indexing. Here's the basic situation: Given a rank-2 array
        > > (i.e., a matrix) it seems to be trivial, with array indexing,
        > > to extract a subset of its *columns*. But it does not seem
        > > to be trivial to extract a subset of its *rows*.[/color]
        >
        > You can do this using slices, like so:
        >[color=green][color=darkred]
        > >>> from numarray import *
        > >>> a = array([[1, 2], [3, 4]])
        > >>> a[:,1][/color][/color]
        > array([2, 4])
        >
        > ':' means 'take all values along this axis', just like how with standard
        > Python lists it means 'take all values in the list'.[/color]

        But that just gets me *one* column. I was trying to extract
        an arbitrary subset of columns. Like I pointed out in the example
        code I gave, this is trivial get take(), but does not seem to
        be trivial with array indexing (and impossible with slicing).
        Mike

        Comment

        • Michael Drumheller

          #5
          Re: NumArray array-indexing

          Christopher T King <squirrel@WPI.E DU> wrote in message news:<Pine.LNX. 4.44.0408121444 370.9594-100000@ccc8.wpi .edu>...[color=blue]
          > On Thu, 12 Aug 2004, Christopher T King wrote:
          >[color=green]
          > > On 12 Aug 2004, Michael Drumheller wrote:
          > >[color=darkred]
          > > > Basically, it seems to me that NumArray simply does not support
          > > > the distinction between a column vector and a row vector. That
          > > > is, if you have x=[1,2,3], then transpose(x) is a no-op. True?[/color]
          > >
          > > False. You have to supply numarray with a two-dimensional array in order
          > > to perform a two-dimensional transpose:[/color]
          >
          > Where by "False" I meant "The first sentence is false, but the second
          > sentence is true". Column vectors and row vectors must be represented as
          > two-dimensional arrays; transpose() of a one-dimensional array is a no-op
          > since all transpose() does (by default) is reverse the order of the axes.[/color]

          I understand that, but I think it just goes to support my contention that
          NumArray does not support transposed vectors *from an array-indexing point
          of view.* Here is what I mean:

          As you pointed out in your previous message, you can get "the transpose
          of a row vector" if the "row vector" is actually a single-row matrix,
          i.e.,
          [color=blue][color=green][color=darkred]
          >>> transpose([[1, 2, 3]])[/color][/color][/color]
          array([[1],
          [2],
          [3]])

          However, whereas [1, 2, 3] passed as an index-array will get you the
          second, third, and fourth rows of a rank-2 matrix, [[1,2,3]] will *not*
          do that. (It gets you some other weird thing that I can't remember.)
          That is, a single-row matrix may be the same thing as a row vector
          in a mathematical context, but it is not the same thing in an
          array-indexing context. Similarly, passing [[1],
          [2],
          [3]]
          as an index array doesn't get you anything remotely like the second
          third, and fourth columns. So it seems to me that array indexing
          can easily get you an arbitrary subset of rows, but not an arbitrary
          subset of columns. Would you agree?
          By the way: Thank you for your attention to my problem!
          Mike

          Comment

          • Peter Otten

            #6
            Re: NumArray array-indexing

            Michael Drumheller wrote:
            [color=blue]
            > array-indexing. Here's the basic situation: Given a rank-2 array
            > (i.e., a matrix) it seems to be trivial, with array indexing,
            > to extract a subset of its columns. But it does not seem
            > to be trivial to extract a subset of its rows. The code[/color]

            Could it be you are looking for the Ellipsis (...)?
            [color=blue][color=green][color=darkred]
            >>> a = numarray.array( range(9), shape=[3,3])
            >>> a[/color][/color][/color]
            array([[0, 1, 2],
            [3, 4, 5],
            [6, 7, 8]])
            [color=blue][color=green][color=darkred]
            >>> a[0:2][/color][/color][/color]
            array([[0, 1, 2],
            [3, 4, 5]])[color=blue][color=green][color=darkred]
            >>> a[..., 1][/color][/color][/color]
            array([1, 4, 7])[color=blue][color=green][color=darkred]
            >>> a[..., 1:][/color][/color][/color]
            array([[1, 2],
            [4, 5],
            [7, 8]])[color=blue][color=green][color=darkred]
            >>> a[..., 0:3:2][/color][/color][/color]
            array([[0, 2],
            [3, 5],
            [6, 8]])

            Of course in 2D you do not really need it:
            [color=blue][color=green][color=darkred]
            >>> a[:, :2][/color][/color][/color]
            array([[0, 1],
            [3, 4],
            [6, 7]])


            But at some point it may make things clearer:
            [color=blue][color=green][color=darkred]
            >>> a = numarray.array( range(2**10), shape=[2]*10)
            >>> a[...,:][(-1,)*7][/color][/color][/color]
            array([[[1016, 1017],
            [1018, 1019]],

            [[1020, 1021],
            [1022, 1023]]])

            Peter

            Comment

            • Christopher T King

              #7
              Re: NumArray array-indexing

              On 16 Aug 2004, Michael Drumheller wrote:
              [color=blue]
              > However, whereas [1, 2, 3] passed as an index-array will get you the
              > second, third, and fourth rows of a rank-2 matrix, [[1,2,3]] will *not*
              > do that. (It gets you some other weird thing that I can't remember.)
              > That is, a single-row matrix may be the same thing as a row vector
              > in a mathematical context, but it is not the same thing in an
              > array-indexing context. Similarly, passing [[1],
              > [2],
              > [3]]
              > as an index array doesn't get you anything remotely like the second
              > third, and fourth columns. So it seems to me that array indexing
              > can easily get you an arbitrary subset of rows, but not an arbitrary
              > subset of columns. Would you agree?[/color]

              Forgive the poor flow of the following; I've rewritten it a couple of
              times.

              Think about what you're trying to do for a second. You want to pass a
              list of indices to extract along a given axis. You need three pieces of
              information to do this: which indices, which axis, and possibly the
              geometry of the output vector. You're supplying the wrong information;
              you're supplying which indices, and a geometry. Matlab guesses the right
              information (which axis) from the wrong information (the geometry).

              When you index a 2-dimensional array in Matlab, what happens? If the
              index array is a row vector, then the indices you supply index the first
              dimension. If the index array is a column vector, then the indices index
              the second dimension. But what if the index array is two-dimensional?
              Which dimension should the indices index? (For the record, they seem to
              index the second dimension.)

              numarray, on the other hand, provides an exact mechanism for supplying
              index arrays thusly:
              [color=blue][color=green][color=darkred]
              >>> a=array([[1,2,3],[4,5,6],[7,8,9]])
              >>> a[[1,2],[0,0]][/color][/color][/color]
              array([4,7])

              In this example, [1,2] are the row indices, and [0,0] are the column
              indices (the information Matlab guesses for you). You can abbreviate
              [0,0] as just 0:
              [color=blue][color=green][color=darkred]
              >>> a[[1,2],0][/color][/color][/color]
              array([4,7])

              (try the previous in Matlab; you will get similar results)

              You can index along another column vector if you want:
              [color=blue][color=green][color=darkred]
              >>> a[[1,2],1][/color][/color][/color]
              array([5,8])

              Or you can arbitrarily index both dimensions (AFAICT, something not
              possible in Matlab):
              [color=blue][color=green][color=darkred]
              >>> a[[1,2],[0,1]][/color][/color][/color]
              array([4,8])

              Note that doing the above in Matlab results in a 2x2 matrix, probably not
              what was wanted. The explicit numarray equivalent to that Matlab
              construction is a[[[1],[2]],[[0,1]]].

              Note also that the output vector takes the shape of the index vector:
              [color=blue][color=green][color=darkred]
              >>> a[[[1,2]],0][/color][/color][/color]
              array([[4,7]])[color=blue][color=green][color=darkred]
              >>> a[[[1],[2]],0][/color][/color][/color]
              array([[4],
              [7]])

              So the answer to your question is, yes, not only can you use arbitrary
              array indices in numarray, they're more powerful than the Matlab
              equivalent. Yet another reason why explicit is better than implicit.

              Comment

              Working...