[Scipy-svn] r3959 - in trunk/scipy/sparse: . tests
scipy-svn at scipy.org
scipy-svn at scipy.org
Wed Feb 27 00:35:40 EST 2008
Author: wnbell
Date: 2008-02-26 23:35:35 -0600 (Tue, 26 Feb 2008)
New Revision: 3959
Modified:
trunk/scipy/sparse/csc.py
trunk/scipy/sparse/csr.py
trunk/scipy/sparse/tests/test_base.py
Log:
added fancy indexing to CSC matrix
Modified: trunk/scipy/sparse/csc.py
===================================================================
--- trunk/scipy/sparse/csc.py 2008-02-26 20:55:11 UTC (rev 3958)
+++ trunk/scipy/sparse/csc.py 2008-02-27 05:35:35 UTC (rev 3959)
@@ -7,12 +7,12 @@
import numpy
from numpy import array, matrix, asarray, asmatrix, zeros, rank, intc, \
empty, hstack, isscalar, ndarray, shape, searchsorted, where, \
- concatenate, deprecate
+ concatenate, deprecate, transpose, ravel
from base import spmatrix, isspmatrix
from sparsetools import csc_tocsr
from sputils import upcast, to_native, isdense, isshape, getdtype, \
- isscalarlike
+ isscalarlike, isintlike
from compressed import _cs_matrix
@@ -131,7 +131,38 @@
A.has_sorted_indices = True
return A
-
+
+ def __getitem__(self, key):
+ # use CSR to implement fancy indexing
+ if isinstance(key, tuple):
+ row = key[0]
+ col = key[1]
+
+ if isintlike(row) or isinstance(row, slice):
+ return self.T[col,row].T
+ else:
+ #[[1,2],??] or [[[1],[2]],??]
+ if isintlike(col) or isinstance(col,slice):
+ return self.T[col,row].T
+ else:
+ row = asarray(row, dtype='intc')
+ col = asarray(col, dtype='intc')
+ if len(row.shape) == 1:
+ return self.T[col,row]
+ elif len(row.shape) == 2:
+ row = row.reshape(-1)
+ col = col.reshape(-1,1)
+ return self.T[col,row].T
+ else:
+ raise NotImplementedError('unsupported indexing')
+
+ return self.T[col,row].T
+ elif isintlike(key) or isinstance(key,slice):
+ return self.T[:,key].T #[i] or [1:2]
+ else:
+ return self.T[:,key].T #[[1,2]]
+
+
# these functions are used by the parent class (_cs_matrix)
# to remove redudancy between csc_matrix and csr_matrix
def _swap(self,x):
Modified: trunk/scipy/sparse/csr.py
===================================================================
--- trunk/scipy/sparse/csr.py 2008-02-26 20:55:11 UTC (rev 3958)
+++ trunk/scipy/sparse/csr.py 2008-02-27 05:35:35 UTC (rev 3959)
@@ -8,7 +8,7 @@
import numpy
from numpy import array, matrix, asarray, asmatrix, zeros, rank, intc, \
empty, hstack, isscalar, ndarray, shape, searchsorted, where, \
- concatenate, deprecate, arange, ones
+ concatenate, deprecate, arange, ones, ravel
from base import spmatrix, isspmatrix
from sparsetools import csr_tocsc, csr_tobsr, csr_count_blocks, \
@@ -240,22 +240,34 @@
else:
P = extractor(col,self.shape[1]).T #[1:2,[1,2]]
return self[row,:]*P
+
else:
- #[[1,2],??]
+ #[[1,2],??] or [[[1],[2]],??]
if isintlike(col) or isinstance(col,slice):
- P = extractor(row, self.shape[0])
- return (P*self)[:,col] #[[1,2],j] or [[1,2],1:2]
+ P = extractor(row, self.shape[0]) #[[1,2],j] or [[1,2],1:2]
+ return (P*self)[:,col]
+
else:
- row = asindices(row) #[[1,2],[1,2]]
- col = asindices(col)
- if len(row) != len(col):
- raise IndexError('number of row and column indices differ')
- val = []
- for i,j in zip(row,col):
- val.append(self._get_single_element(i,j))
- return asmatrix(val)
+ row = asindices(row)
+ col = asindices(col)
+ if len(row.shape) == 1:
+ if len(row) != len(col): #[[1,2],[1,2]]
+ raise IndexError('number of row and column indices differ')
+ val = []
+ for i,j in zip(row,col):
+ val.append(self._get_single_element(i,j))
+ return asmatrix(val)
+
+ elif len(row.shape) == 2:
+ row = ravel(row) #[[[1],[2]],[1,2]]
+ P = extractor(row, self.shape[0])
+ return (P*self)[:,col]
+ else:
+ raise NotImplementedError('unsupported indexing')
+
+
elif isintlike(key) or isinstance(key,slice):
return self[key,:] #[i] or [1:2]
else:
Modified: trunk/scipy/sparse/tests/test_base.py
===================================================================
--- trunk/scipy/sparse/tests/test_base.py 2008-02-26 20:55:11 UTC (rev 3958)
+++ trunk/scipy/sparse/tests/test_base.py 2008-02-27 05:35:35 UTC (rev 3959)
@@ -651,24 +651,69 @@
"""Tests fancy indexing features. The tests for any matrix formats
that implement these features should derive from this class.
"""
- # This isn't supported by any matrix objects yet:
- def test_sequence_indexing(self):
- B = asmatrix(arange(50.).reshape(5,10))
- A = self.spmatrix(B)
- assert_array_equal(B[(1,2),(3,4)], A[(1,2),(3,4)].todense())
- assert_array_equal(B[(1,2,3),(3,4,5)], A[(1,2,3),(3,4,5)].todense())
-
def test_fancy_indexing(self):
- """Test for new indexing functionality"""
- B = ones((5,10), float)
- A = dok_matrix(B)
- # Write me!
+ B = asmatrix(arange(50).reshape(5,10))
+ A = self.spmatrix( B )
- # Both slicing and fancy indexing: not yet supported
- # assert_array_equal(B[(1,2),:], A[(1,2),:].todense())
- # assert_array_equal(B[(1,2,3),:], A[(1,2,3),:].todense())
+ # [i,j]
+ assert_equal(A[2,3],B[2,3])
+ assert_equal(A[-1,8],B[-1,8])
+ assert_equal(A[-1,-2],B[-1,-2])
+ # [i,1:2]
+ assert_equal(A[2,:].todense(),B[2,:])
+ assert_equal(A[2,5:-2].todense(),B[2,5:-2])
+
+ # [i,[1,2]]
+ assert_equal(A[3,[1,3]].todense(),B[3,[1,3]])
+ assert_equal(A[-1,[2,-5]].todense(),B[-1,[2,-5]])
+ # [1:2,j]
+ assert_equal(A[:,2].todense(),B[:,2])
+ assert_equal(A[3:4,9].todense(),B[3:4,9])
+ assert_equal(A[1:4,-5].todense(),B[1:4,-5])
+
+ # [1:2,[1,2]]
+ assert_equal(A[:,[2,8,3,-1]].todense(),B[:,[2,8,3,-1]])
+ assert_equal(A[3:4,[9]].todense(),B[3:4,[9]])
+ assert_equal(A[1:4,[-1,-5]].todense(),B[1:4,[-1,-5]])
+
+ # [[1,2],j]
+ assert_equal(A[[1,3],3].todense(),B[[1,3],3])
+ assert_equal(A[[2,-5],-4].todense(),B[[2,-5],-4])
+
+ # [[1,2],1:2]
+ assert_equal(A[[1,3],:].todense(),B[[1,3],:])
+ assert_equal(A[[2,-5],8:-1].todense(),B[[2,-5],8:-1])
+
+ # [[1,2],[1,2]]
+ assert_equal(A[[1,3],[2,4]],B[[1,3],[2,4]])
+ assert_equal(A[[-1,-3],[2,-4]],B[[-1,-3],[2,-4]])
+
+ # [[[1],[2]],[1,2]]
+ assert_equal(A[[[1],[3]],[2,4]].todense(),B[[[1],[3]],[2,4]])
+ assert_equal(A[[[-1],[-3],[-2]],[2,-4]].todense(),B[[[-1],[-3],[-2]],[2,-4]])
+
+ # [i]
+ assert_equal(A[1].todense(),B[1])
+ assert_equal(A[-2].todense(),B[-2])
+
+ # [1:2]
+ assert_equal(A[1:4].todense(),B[1:4])
+ assert_equal(A[1:-2].todense(),B[1:-2])
+
+ # [[1,2]]
+ assert_equal(A[[1,3]].todense(),B[[1,3]])
+ assert_equal(A[[-1,-3]].todense(),B[[-1,-3]])
+
+ # [[1,2],:][:,[1,2]]
+ assert_equal(A[[1,3],:][:,[2,4]].todense(), B[[1,3],:][:,[2,4]] )
+ assert_equal(A[[-1,-3],:][:,[2,-4]].todense(), B[[-1,-3],:][:,[2,-4]] )
+
+ # [:,[1,2]][[1,2],:]
+ assert_equal(A[:,[1,3]][[2,4],:].todense(), B[:,[1,3]][[2,4],:] )
+ assert_equal(A[:,[-1,-3]][[2,-4],:].todense(), B[:,[-1,-3]][[2,-4],:] )
+
class _TestArithmetic:
"""
Test real/complex arithmetic
@@ -768,7 +813,7 @@
class TestCSR(_TestCommon, _TestGetSet, _TestSolve,
_TestInplaceArithmetic, _TestArithmetic, _TestMatvecOutput,
_TestHorizSlicing, _TestVertSlicing, _TestBothSlicing,
- TestCase):
+ _TestFancyIndexing, TestCase):
spmatrix = csr_matrix
def test_constructor1(self):
@@ -861,70 +906,11 @@
assert_array_equal(asp.todense(),bsp.todense())
- def test_fancy_slicing(self):
- #TODO add this to csc_matrix
- B = asmatrix(arange(50).reshape(5,10))
- A = csr_matrix( B )
- # [i,j]
- assert_equal(A[2,3],B[2,3])
- assert_equal(A[-1,8],B[-1,8])
- assert_equal(A[-1,-2],B[-1,-2])
-
- # [i,1:2]
- assert_equal(A[2,:].todense(),B[2,:])
- assert_equal(A[2,5:-2].todense(),B[2,5:-2])
-
- # [i,[1,2]]
- assert_equal(A[3,[1,3]].todense(),B[3,[1,3]])
- assert_equal(A[-1,[2,-5]].todense(),B[-1,[2,-5]])
-
- # [1:2,j]
- assert_equal(A[:,2].todense(),B[:,2])
- assert_equal(A[3:4,9].todense(),B[3:4,9])
- assert_equal(A[1:4,-5].todense(),B[1:4,-5])
-
- # [1:2,[1,2]]
- assert_equal(A[:,[2,8,3,-1]].todense(),B[:,[2,8,3,-1]])
- assert_equal(A[3:4,[9]].todense(),B[3:4,[9]])
- assert_equal(A[1:4,[-1,-5]].todense(),B[1:4,[-1,-5]])
-
- # [[1,2],j]
- assert_equal(A[[1,3],3].todense(),B[[1,3],3])
- assert_equal(A[[2,-5],-4].todense(),B[[2,-5],-4])
-
- # [[1,2],1:2]
- assert_equal(A[[1,3],:].todense(),B[[1,3],:])
- assert_equal(A[[2,-5],8:-1].todense(),B[[2,-5],8:-1])
-
- # [[1,2],[1,2]]
- assert_equal(A[[1,3],[2,4]],B[[1,3],[2,4]])
- assert_equal(A[[-1,-3],[2,-4]],B[[-1,-3],[2,-4]])
-
- # [i]
- assert_equal(A[1].todense(),B[1])
- assert_equal(A[-2].todense(),B[-2])
-
- # [1:2]
- assert_equal(A[1:4].todense(),B[1:4])
- assert_equal(A[1:-2].todense(),B[1:-2])
-
- # [[1,2]]
- assert_equal(A[[1,3]].todense(),B[[1,3]])
- assert_equal(A[[-1,-3]].todense(),B[[-1,-3]])
-
- # [[1,2],:][:,[1,2]]
- assert_equal(A[[1,3],:][:,[2,4]].todense(), B[[1,3],:][:,[2,4]] )
- assert_equal(A[[-1,-3],:][:,[2,-4]].todense(), B[[-1,-3],:][:,[2,-4]] )
-
- # [:,[1,2]][[1,2],:]
- assert_equal(A[:,[1,3]][[2,4],:].todense(), B[:,[1,3]][[2,4],:] )
- assert_equal(A[:,[-1,-3]][[2,-4],:].todense(), B[:,[-1,-3]][[2,-4],:] )
-
class TestCSC(_TestCommon, _TestGetSet, _TestSolve,
_TestInplaceArithmetic, _TestArithmetic, _TestMatvecOutput,
_TestHorizSlicing, _TestVertSlicing, _TestBothSlicing,
- TestCase):
+ _TestFancyIndexing, TestCase):
spmatrix = csc_matrix
def test_constructor1(self):
More information about the Scipy-svn
mailing list