Re: problems with duplicating and slicing an array

Discussion in 'Python' started by Yun Mao, Jan 21, 2005.

  1. Yun Mao

    Yun Mao Guest

    Hi all,
    Thanks for the help. numarray doesn't provide what I look for either. e.g.
    a = array( [[1,2,3],[4,5,6]] )
    I sometimes what this: a[ [1,0], :], or even
    a[ [1,0], [0,1] ] , which should give me
    [[4, 5], [1,2]]

    Because I don't really care about arrays with dimension >2, I did a
    little hacking with Numeric.Matrix.Matrix. It is more compatible with
    Matlab style slicing (except that the index starts from 0, not 1).
    This class automatically does copy, which is what I needed.
    Here is the code if somebody is interested (The wordy getAttr part is
    due to a "feature" in Numeric.Matrix based on the assumption that
    probably nobody is going to inherent it again :) ):

    #==========begin code=========
    from Numeric import *
    from Matrix import Matrix, UserArray
    import types

    def _isSeq(t):
    if isinstance(t, types.ListType):
    return True
    if (isinstance(t, ArrayType) or isinstance(t, UserArray)):
    return len(t.shape)==1 or \
    (len(t.shape)==2 and t.shape[0]==1)
    return False

    class Mat(Matrix):
    def __getitem__(self, index):
    """Matlab style slicing:
    e.g. a[ [3,2], [2,1] ], a[1]
    """
    if isinstance(index, types.TupleType) and len(index)==1 \
    or _isSeq(index):
    if self.array.shape[0]!=1:
    return self._rc(self.array.flat).__getitem__(index)
    if not _isSeq(index):
    return Matrix.__getitem__(self, index)
    return self._rc(take(self, array(index).flat, 1))
    elif isinstance(index, types.TupleType):
    assert len(index)==2
    if not (_isSeq(index[0]) or _isSeq(index[1])):
    return Matrix.__getitem__(self, index)
    r = self.array
    tmp = slice(None, None, None)
    if _isSeq(index[0]):
    r = take(r, array(index[0]).flat,0)
    else:
    r = self._rc(r).__getitem__(self, (index[0], tmp))
    if _isSeq(index[1]):
    r = take(r, array(index[1]).flat,1)
    else:
    r = self._rc(r).__getitem__( (tmp,index[1]))
    return self._rc(r)
    elif isinstance(index, types.IntType):
    return self.array.flat[index]
    return Matrix.__getitem__(self, index)

    def __getattr__(self, attr):
    if attr == 'A':
    return squeeze(self.array)
    elif attr == 'T':
    return self._rc(Numeric.transpose(self.array))
    elif attr == 'H':
    if len(self.array.shape) == 1:
    self.array.shape = (1,self.array.shape[0])
    return self._rc(Numeric.conjugate(Numeric.transpose(self.array)))
    elif attr == 'I':
    return self._rc(LinearAlgebra.inverse(self.array))
    elif attr == 'real':
    return self._rc(self.array.real)
    elif attr == 'imag':
    return self._rc(self.array.imag)
    elif attr == 'flat':
    return self._rc(self.array.flat)
    elif attr == 'length':
    return max(self.array.shape)
    else:
    raise AttributeError, attr + " not found."
    #========end code========


    > numarray supports matlab style indexing if you pass the ind as an
    > array or list of indices (but not a tuple, I found to my surprise).
    > As pointed out already, for Numeric you need to use the take function
    >
    > >>> from numarray import array
    > >>> x = array([1,2,3,4,5,6,7,8,9])
    > >>> ind = [3,5,7]
    > >>> inda = array(ind)
    > >>> indt = tuple(ind)
    > >>> x[ind]

    > array([4, 6, 8])
    > >>> x[inda]

    > array([4, 6, 8])
    > >>> x[indt]

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > IndexError: too many indices.
    >
    > I'm sure the tuple "surprise" is a documented feature.
    >
    > JDH
    >
    Yun Mao, Jan 21, 2005
    #1
    1. Advertising

  2. Yun Mao

    Guest

    Yun Mao wrote:
    >Thanks for the help. numarray doesn't provide what I look for either.

    e.g.
    >a = array( [[1,2,3],[4,5,6]] )
    >I sometimes what this: a[ [1,0], :], or even
    >a[ [1,0], [0,1] ] , which should give me
    >[[4, 5], [1,2]]


    I think Fortran 90 and 95 have the array slicing you want. For example,
    if

    imat =
    11 12 13
    21 22 23

    then imat([2,1,2],:)) =
    21 22 23
    11 12 13
    21 22 23

    and imat([2,1,2],[1,3]) =
    21 23
    11 13
    21 23

    Like Matlab, Fortran arrays by default start with 1, and x(i:j) gives a
    slice of elements including x(j). There are free compilers g95 (in
    beta) and gfortran (in alpha).
    , Jan 21, 2005
    #2
    1. Advertising

  3. py> import numarray as na
    py> a = na.array([[1,2,3],[4,5,6]])

    Yun Mao wrote:
    > Thanks for the help. numarray doesn't provide what I look for either. e.g.
    > a = array( [[1,2,3],[4,5,6]] )
    > I sometimes what this: a[ [1,0], :],


    py> a[[1,0]]
    array([[4, 5, 6],
    [1, 2, 3]])

    > or even a[ [1,0], [0,1] ] , which should give me
    > [[4, 5], [1,2]]


    py> a[:,:2][[1,0]][[0,1]]
    array([[4, 5],
    [1, 2]])

    Not the same syntax, of course, but doable.

    Steve
    Steven Bethard, Jan 21, 2005
    #3
  4. Yun Mao

    David Isaac Guest

    Yun Mao wrote:
    >a[ [1,0], [0,1] ] , which should give me
    >[[4, 5], [1,2]]


    Numeric:
    take(take(a,[1,0]),[0,1],1)

    fwiw,
    Alan Isaac
    David Isaac, Jan 23, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tero Kapanen

    Slicing of an array: wrong direction

    Tero Kapanen, Nov 4, 2003, in forum: VHDL
    Replies:
    11
    Views:
    7,236
    Allan Herriman
    Nov 7, 2003
  2. Yun Mao
    Replies:
    2
    Views:
    308
  3. jeg

    2d array slicing problem

    jeg, Oct 7, 2005, in forum: Python
    Replies:
    4
    Views:
    395
    Robert Kern
    Nov 27, 2005
  4. Steven W. Orr

    Further adventures in array slicing.

    Steven W. Orr, May 4, 2007, in forum: Python
    Replies:
    3
    Views:
    267
    Alex Martelli
    May 5, 2007
  5. Aljosa Mohorovic
    Replies:
    0
    Views:
    275
    Aljosa Mohorovic
    Nov 27, 2009
Loading...

Share This Page