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 > -- http://mail.python.org/mailman/listinfo/python-list