Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: problems with duplicating and slicing an array

Reply
Thread Tools

Re: problems with duplicating and slicing an array

 
 
Yun Mao
Guest
Posts: n/a
 
      01-21-2005
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
>

 
Reply With Quote
 
 
 
 
beliavsky@aol.com
Guest
Posts: n/a
 
      01-21-2005
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).

 
Reply With Quote
 
 
 
 
Steven Bethard
Guest
Posts: n/a
 
      01-21-2005
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
 
Reply With Quote
 
David Isaac
Guest
Posts: n/a
 
      01-23-2005
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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Slicing an array in groups of eight Graham Arden Python 3 05-21-2009 10:14 PM
Further adventures in array slicing. Steven W. Orr Python 3 05-05-2007 02:35 AM
2d array slicing problem jeg Python 4 11-27-2005 01:34 AM
problems with duplicating and slicing an array Yun Mao Python 2 01-21-2005 02:21 AM
Slicing of an array: wrong direction Tero Kapanen VHDL 11 11-07-2003 02:03 AM



Advertisments