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 = np.asarray(row, dtype=np.intc) col = np.asarray(col, dtype=np.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]]
def __getitem__(self, key): if isinstance(key, tuple): row = key[0] col = key[1] #TODO implement CSR[ [1,2,3], X ] with sparse matmat #TODO make use of sorted indices if isintlike(row) and isintlike(col): return self._get_single_element(row, col) else: major, minor = self._swap((row, col)) if isintlike(major) and isinstance(minor, slice): minor_shape = self._swap(self.shape)[1] start, stop, stride = minor.indices(minor_shape) out_shape = self._swap((1, stop - start)) return self._get_slice(major, start, stop, stride, out_shape) elif isinstance(row, slice) or isinstance(col, slice): return self._get_submatrix(row, col) else: raise NotImplementedError elif isintlike(key): return self[key, :] else: raise IndexError("invalid index")
def __getitem__(self, key): if isinstance(key, tuple): row = key[0] col = key[1] #TODO implement CSR[ [1,2,3], X ] with sparse matmat #TODO make use of sorted indices if isintlike(row) and isintlike(col): return self._get_single_element(row,col) else: major,minor = self._swap((row,col)) if isintlike(major) and isinstance(minor,slice): minor_shape = self._swap(self.shape)[1] start, stop, stride = minor.indices(minor_shape) out_shape = self._swap( (1, stop-start) ) return self._get_slice( major, start, stop, stride, out_shape) elif isinstance( row, slice) or isinstance(col, slice): return self._get_submatrix( row, col ) else: raise NotImplementedError elif isintlike(key): return self[key, :] else: raise IndexError("invalid index")
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 = np.asarray(row, dtype=np.intc) col = np.asarray(col, dtype=np.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]]
def get(self, key, default=0.): """This overrides the dict.get method, providing type checking but otherwise equivalent functionality. """ try: i, j = key assert isintlike(i) and isintlike(j) except (AssertionError, TypeError, ValueError): raise IndexError('index must be a pair of integers') if (i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]): raise IndexError('index out of bounds') return dict.get(self, key, default)
def process_slice(sl, num): if isinstance(sl, slice): if sl.step not in (1, None): raise ValueError('slicing with step != 1 not supported') i0, i1 = sl.start, sl.stop if i0 is None: i0 = 0 elif i0 < 0: i0 = num + i0 if i1 is None: i1 = num elif i1 < 0: i1 = num + i1 return i0, i1 elif isintlike(sl): if sl < 0: sl += num return sl, sl + 1 else: raise TypeError('expected slice or scalar')
def __pow__(self, other): if self.shape[0] != self.shape[1]: raise TypeError('matrix is not square') if isintlike(other): other = int(other) if other < 0: raise ValueError('exponent must be >= 0') if other == 0: from construct import identity return identity( self.shape[0], dtype=self.dtype ) elif other == 1: return self.copy() else: result = self for i in range(1,other): result = result*self return result elif isscalarlike(other): raise ValueError('exponent must be an integer') elif isspmatrix(other): warn('Using ** for elementwise multiplication is deprecated.'\ 'Use .multiply() instead', DeprecationWarning) return self.multiply(other) else: raise NotImplementedError
def process_slice(sl, num): if isinstance(sl, slice): if sl.step not in (1, None): raise ValueError("slicing with step != 1 not supported") i0, i1 = sl.start, sl.stop if i0 is None: i0 = 0 elif i0 < 0: i0 = num + i0 if i1 is None: i1 = num elif i1 < 0: i1 = num + i1 return i0, i1 elif isintlike(sl): if sl < 0: sl += num return sl, sl + 1 else: raise TypeError("expected slice or scalar")
def process_slice(sl, num): if isinstance(sl, slice): i0, i1 = sl.start, sl.stop if i0 is None: i0 = 0 elif i0 < 0: i0 = num + i0 if i1 is None: i1 = num elif i1 < 0: i1 = num + i1 return i0, i1 elif isintlike(sl): if sl < 0: sl += num return sl, sl + 1 else: raise TypeError('expected slice or scalar')
def __pow__(self, other): if self.shape[0] != self.shape[1]: raise TypeError('matrix is not square') if isintlike(other): other = int(other) if other < 0: raise ValueError('exponent must be >= 0') if other == 0: from construct import identity return identity( self.shape[0], dtype=self.dtype ) elif other == 1: return self.copy() else: result = self for i in range(1,other): result = result*self return result elif isscalarlike(other): raise ValueError('exponent must be an integer') else: raise NotImplementedError
def process_slice( sl, num ): if isinstance( sl, slice ): i0, i1 = sl.start, sl.stop if i0 is None: i0 = 0 elif i0 < 0: i0 = num + i0 if i1 is None: i1 = num elif i1 < 0: i1 = num + i1 return i0, i1 elif isintlike( sl ): if sl < 0: sl += num return sl, sl + 1 else: raise TypeError('expected slice or scalar')
def __getitem__(self, key): def asindices(x): try: x = np.asarray(x, dtype=np.intc) except: raise IndexError('invalid index') else: return x def check_bounds(indices, N): max_indx = indices.max() if max_indx >= N: raise IndexError('index (%d) out of range' % max_indx) min_indx = indices.min() if min_indx < -N: raise IndexError('index (%d) out of range' % (N + min_indx)) return (min_indx, max_indx) def extractor(indices, N): """Return a sparse matrix P so that P*self implements slicing of the form self[[1,2,3],:] """ indices = asindices(indices) (min_indx, max_indx) = check_bounds(indices, N) if min_indx < 0: indices = indices.copy() indices[indices < 0] += N indptr = np.arange(len(indices) + 1, dtype=np.intc) data = np.ones(len(indices), dtype=self.dtype) shape = (len(indices), N) return csr_matrix((data, indices, indptr), shape=shape) if isinstance(key, tuple): row = key[0] col = key[1] if isintlike(row): #[1,??] if isintlike(col): return self._get_single_element(row, col) #[i,j] elif isinstance(col, slice): return self._get_row_slice(row, col) #[i,1:2] else: P = extractor(col, self.shape[1]).T #[i,[1,2]] return self[row, :] * P elif isinstance(row, slice): #[1:2,??] if isintlike(col) or isinstance(col, slice): return self._get_submatrix(row, col) #[1:2,j] else: P = extractor(col, self.shape[1]).T #[1:2,[1,2]] return self[row, :] * P else: #[[1,2],??] or [[[1],[2]],??] if isintlike(col) or isinstance(col, slice): P = extractor(row, self.shape[0]) #[[1,2],j] or [[1,2],1:2] return (P * self)[:, col] else: 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') check_bounds(row, self.shape[0]) check_bounds(col, self.shape[1]) num_samples = len(row) val = np.empty(num_samples, dtype=self.dtype) csr_sample_values(self.shape[0], self.shape[1], self.indptr, self.indices, self.data, num_samples, row, col, val) #val = [] #for i,j in zip(row,col): # val.append(self._get_single_element(i,j)) return np.asmatrix(val) elif len(row.shape) == 2: row = np.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: return self[asindices(key), :] #[[1,2]]
def __init__(self, arg1, shape=None, dtype=None, copy=False): _data_matrix.__init__(self) if isinstance(arg1, tuple): if isshape(arg1): M, N = arg1 self.shape = (M,N) self.row = np.array([], dtype=np.intc) self.col = np.array([], dtype=np.intc) self.data = np.array([], getdtype(dtype, default=float)) else: try: obj, ij = arg1 except: raise TypeError('invalid input format') try: if len(ij) != 2: raise TypeError except TypeError: raise TypeError('invalid input format') self.row = np.array(ij[0], copy=copy, dtype=np.intc) self.col = np.array(ij[1], copy=copy, dtype=np.intc) self.data = np.array( obj, copy=copy) if shape is None: if len(self.row) == 0 or len(self.col) == 0: raise ValueError('cannot infer dimensions from zero sized index arrays') M = self.row.max() + 1 N = self.col.max() + 1 self.shape = (M, N) else: # Use 2 steps to ensure shape has length 2. M, N = shape self.shape = (M, N) elif arg1 is None: # Initialize an empty matrix. if not isinstance(shape, tuple) or not isintlike(shape[0]): raise TypeError('dimensions not understood') warn('coo_matrix(None, shape=(M,N)) is deprecated, ' \ 'use coo_matrix( (M,N) ) instead', DeprecationWarning) self.shape = shape self.data = np.array([], getdtype(dtype, default=float)) self.row = np.array([], dtype=np.intc) self.col = np.array([], dtype=np.intc) else: if isspmatrix(arg1): if isspmatrix_coo(arg1) and copy: self.row = arg1.row.copy() self.col = arg1.col.copy() self.data = arg1.data.copy() self.shape = arg1.shape else: coo = arg1.tocoo() self.row = coo.row self.col = coo.col self.data = coo.data self.shape = coo.shape else: #dense argument try: M = np.atleast_2d(np.asarray(arg1)) except: raise TypeError('invalid input format') if np.rank(M) != 2: raise TypeError('expected rank <= 2 array or matrix') self.shape = M.shape self.row,self.col = (M != 0).nonzero() self.data = M[self.row,self.col] if dtype is not None: self.data = self.data.astype(dtype) self._check()
def __setitem__(self, key, value): try: i, j = key except (ValueError, TypeError): raise TypeError("index must be a pair of integers or slices") # First deal with the case where both i and j are integers if isintlike(i) and isintlike(j): if i < 0: i += self.shape[0] if j < 0: j += self.shape[1] if i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]: raise IndexError("index out of bounds") if np.isscalar(value): if value == 0: if self.has_key((i,j)): del self[(i,j)] else: dict.__setitem__(self, (i,j), self.dtype.type(value)) else: raise ValueError('setting an array element with a sequence') else: # Either i or j is a slice, sequence, or invalid. If i is a slice # or sequence, unfold it first and call __setitem__ recursively. if isinstance(i, slice): # Is there an easier way to do this? seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1) elif _is_sequence(i): seq = i else: # Make sure i is an integer. (But allow it to be a subclass of int). if not isintlike(i): raise TypeError("index must be a pair of integers or slices") seq = None if seq is not None: # First see if 'value' is another dok_matrix of the appropriate # dimensions if isinstance(value, dok_matrix): if value.shape[1] == 1: for element in seq: self[element, j] = value[element, 0] else: raise NotImplementedError("setting a 2-d slice of" " a dok_matrix is not yet supported") elif np.isscalar(value): for element in seq: self[element, j] = value else: # See if value is a sequence try: if len(seq) != len(value): raise ValueError("index and value ranges must" " have the same length") except TypeError: # Not a sequence raise TypeError("unsupported type for" " dok_matrix.__setitem__") # Value is a sequence for element, val in izip(seq, value): self[element, j] = val # don't use dict.__setitem__ # here, since we still want to be able to delete # 0-valued keys, do type checking on 'val' (e.g. if # it's a rank-1 dense array), etc. else: # Process j if isinstance(j, slice): seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1) elif _is_sequence(j): seq = j else: # j is not an integer raise TypeError("index must be a pair of integers or slices") # First see if 'value' is another dok_matrix of the appropriate # dimensions if isinstance(value, dok_matrix): if value.shape[0] == 1: for element in seq: self[i, element] = value[0, element] else: raise NotImplementedError("setting a 2-d slice of" " a dok_matrix is not yet supported") elif np.isscalar(value): for element in seq: self[i, element] = value else: # See if value is a sequence try: if len(seq) != len(value): raise ValueError("index and value ranges must have" " the same length") except TypeError: # Not a sequence raise TypeError("unsupported type for dok_matrix.__setitem__") else: for element, val in izip(seq, value): self[i, element] = val
def __getitem__(self, key): """If key=(i,j) is a pair of integers, return the corresponding element. If either i or j is a slice or sequence, return a new sparse matrix with just these elements. """ try: i, j = key except (ValueError, TypeError): raise TypeError('index must be a pair of integers or slices') # Bounds checking if isintlike(i): if i < 0: i += self.shape[0] if i < 0 or i >= self.shape[0]: raise IndexError('index out of bounds') if isintlike(j): if j < 0: j += self.shape[1] if j < 0 or j >= self.shape[1]: raise IndexError('index out of bounds') # First deal with the case where both i and j are integers if isintlike(i) and isintlike(j): return dict.get(self, (i,j), 0.) else: # Either i or j is a slice, sequence, or invalid. If i is a slice # or sequence, unfold it first and call __getitem__ recursively. if isinstance(i, slice): # Is there an easier way to do this? seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1) elif _is_sequence(i): seq = i else: # Make sure i is an integer. (But allow it to be a subclass of int). if not isintlike(i): raise TypeError('index must be a pair of integers or slices') seq = None if seq is not None: # i is a seq if isintlike(j): # Create a new matrix of the correct dimensions first = seq[0] last = seq[-1] if first < 0 or first >= self.shape[0] or last < 0 \ or last >= self.shape[0]: raise IndexError('index out of bounds') newshape = (last-first+1, 1) new = dok_matrix(newshape) # ** This uses linear time in the size m of dimension 0: # new[0:seq[-1]-seq[0]+1, 0] = \ # [self.get((element, j), 0) for element in seq] # ** Instead just add the non-zero elements. This uses # ** linear time in the number of non-zeros: for (ii, jj) in self.keys(): if jj == j and ii >= first and ii <= last: dict.__setitem__(new, (ii-first, 0), \ dict.__getitem__(self, (ii,jj))) else: ################################### # We should reshape the new matrix here! ################################### raise NotImplementedError("fancy indexing supported over" " one axis only") return new # Below here, j is a sequence, but i is an integer if isinstance(j, slice): # Is there an easier way to do this? seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1) elif _is_sequence(j): seq = j else: # j is not an integer raise TypeError("index must be a pair of integers or slices") # Create a new matrix of the correct dimensions first = seq[0] last = seq[-1] if first < 0 or first >= self.shape[1] or last < 0 \ or last >= self.shape[1]: raise IndexError("index out of bounds") newshape = (1, last-first+1) new = dok_matrix(newshape) # ** This uses linear time in the size n of dimension 1: # new[0, 0:seq[-1]-seq[0]+1] = \ # [self.get((i, element), 0) for element in seq] # ** Instead loop over the non-zero elements. This is slower # ** if there are many non-zeros for (ii, jj) in self.keys(): if ii == i and jj >= first and jj <= last: dict.__setitem__(new, (0, jj-first), \ dict.__getitem__(self, (ii,jj))) return new
def __init__(self, arg1, shape=None, dtype=None, copy=False): _data_matrix.__init__(self) if isinstance(arg1, tuple): if isshape(arg1): M, N = arg1 self.shape = (M, N) self.row = np.array([], dtype=np.intc) self.col = np.array([], dtype=np.intc) self.data = np.array([], getdtype(dtype, default=float)) else: try: obj, ij = arg1 except: raise TypeError('invalid input format') try: if len(ij) != 2: raise TypeError except TypeError: raise TypeError('invalid input format') self.row = np.array(ij[0], copy=copy, dtype=np.intc) self.col = np.array(ij[1], copy=copy, dtype=np.intc) self.data = np.array(obj, copy=copy) if shape is None: if len(self.row) == 0 or len(self.col) == 0: raise ValueError( 'cannot infer dimensions from zero sized index arrays' ) M = self.row.max() + 1 N = self.col.max() + 1 self.shape = (M, N) else: # Use 2 steps to ensure shape has length 2. M, N = shape self.shape = (M, N) elif arg1 is None: # Initialize an empty matrix. if not isinstance(shape, tuple) or not isintlike(shape[0]): raise TypeError('dimensions not understood') warn('coo_matrix(None, shape=(M,N)) is deprecated, ' \ 'use coo_matrix( (M,N) ) instead', DeprecationWarning) self.shape = shape self.data = np.array([], getdtype(dtype, default=float)) self.row = np.array([], dtype=np.intc) self.col = np.array([], dtype=np.intc) else: if isspmatrix(arg1): if isspmatrix_coo(arg1) and copy: self.row = arg1.row.copy() self.col = arg1.col.copy() self.data = arg1.data.copy() self.shape = arg1.shape else: coo = arg1.tocoo() self.row = coo.row self.col = coo.col self.data = coo.data self.shape = coo.shape else: #dense argument try: M = np.atleast_2d(np.asarray(arg1)) except: raise TypeError('invalid input format') if np.rank(M) != 2: raise TypeError('expected rank <= 2 array or matrix') self.shape = M.shape self.row, self.col = M.nonzero() self.data = M[self.row, self.col] if dtype is not None: self.data = self.data.astype(dtype) self._check()
def __setitem__(self, key, value): try: i, j = key except (ValueError, TypeError): raise TypeError("index must be a pair of integers or slices") # First deal with the case where both i and j are integers if isintlike(i) and isintlike(j): if i < 0: i += self.shape[0] if j < 0: j += self.shape[1] if i < 0 or i >= self.shape[0] or j < 0 or j >= self.shape[1]: raise IndexError("index out of bounds") if np.isscalar(value): if value == 0: if self.has_key((i, j)): del self[(i, j)] else: dict.__setitem__(self, (i, j), self.dtype.type(value)) else: raise ValueError('setting an array element with a sequence') else: # Either i or j is a slice, sequence, or invalid. If i is a slice # or sequence, unfold it first and call __setitem__ recursively. if isinstance(i, slice): # Is there an easier way to do this? seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1) elif _is_sequence(i): seq = i else: # Make sure i is an integer. (But allow it to be a subclass of int). if not isintlike(i): raise TypeError( "index must be a pair of integers or slices") seq = None if seq is not None: # First see if 'value' is another dok_matrix of the appropriate # dimensions if isinstance(value, dok_matrix): if value.shape[1] == 1: for element in seq: self[element, j] = value[element, 0] else: raise NotImplementedError( "setting a 2-d slice of" " a dok_matrix is not yet supported") elif np.isscalar(value): for element in seq: self[element, j] = value else: # See if value is a sequence try: if len(seq) != len(value): raise ValueError("index and value ranges must" " have the same length") except TypeError: # Not a sequence raise TypeError("unsupported type for" " dok_matrix.__setitem__") # Value is a sequence for element, val in izip(seq, value): self[element, j] = val # don't use dict.__setitem__ # here, since we still want to be able to delete # 0-valued keys, do type checking on 'val' (e.g. if # it's a rank-1 dense array), etc. else: # Process j if isinstance(j, slice): seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1) elif _is_sequence(j): seq = j else: # j is not an integer raise TypeError( "index must be a pair of integers or slices") # First see if 'value' is another dok_matrix of the appropriate # dimensions if isinstance(value, dok_matrix): if value.shape[0] == 1: for element in seq: self[i, element] = value[0, element] else: raise NotImplementedError( "setting a 2-d slice of" " a dok_matrix is not yet supported") elif np.isscalar(value): for element in seq: self[i, element] = value else: # See if value is a sequence try: if len(seq) != len(value): raise ValueError("index and value ranges must have" " the same length") except TypeError: # Not a sequence raise TypeError( "unsupported type for dok_matrix.__setitem__") else: for element, val in izip(seq, value): self[i, element] = val
def __getitem__(self, key): """If key=(i,j) is a pair of integers, return the corresponding element. If either i or j is a slice or sequence, return a new sparse matrix with just these elements. """ try: i, j = key except (ValueError, TypeError): raise TypeError('index must be a pair of integers or slices') # Bounds checking if isintlike(i): if i < 0: i += self.shape[0] if i < 0 or i >= self.shape[0]: raise IndexError('index out of bounds') if isintlike(j): if j < 0: j += self.shape[1] if j < 0 or j >= self.shape[1]: raise IndexError('index out of bounds') # First deal with the case where both i and j are integers if isintlike(i) and isintlike(j): return dict.get(self, (i, j), 0.) else: # Either i or j is a slice, sequence, or invalid. If i is a slice # or sequence, unfold it first and call __getitem__ recursively. if isinstance(i, slice): # Is there an easier way to do this? seq = xrange(i.start or 0, i.stop or self.shape[0], i.step or 1) elif _is_sequence(i): seq = i else: # Make sure i is an integer. (But allow it to be a subclass of int). if not isintlike(i): raise TypeError( 'index must be a pair of integers or slices') seq = None if seq is not None: # i is a seq if isintlike(j): # Create a new matrix of the correct dimensions first = seq[0] last = seq[-1] if first < 0 or first >= self.shape[0] or last < 0 \ or last >= self.shape[0]: raise IndexError('index out of bounds') newshape = (last - first + 1, 1) new = dok_matrix(newshape) # ** This uses linear time in the size m of dimension 0: # new[0:seq[-1]-seq[0]+1, 0] = \ # [self.get((element, j), 0) for element in seq] # ** Instead just add the non-zero elements. This uses # ** linear time in the number of non-zeros: for (ii, jj) in self.keys(): if jj == j and ii >= first and ii <= last: dict.__setitem__(new, (ii-first, 0), \ dict.__getitem__(self, (ii,jj))) else: ################################### # We should reshape the new matrix here! ################################### raise NotImplementedError("fancy indexing supported over" " one axis only") return new # Below here, j is a sequence, but i is an integer if isinstance(j, slice): # Is there an easier way to do this? seq = xrange(j.start or 0, j.stop or self.shape[1], j.step or 1) elif _is_sequence(j): seq = j else: # j is not an integer raise TypeError("index must be a pair of integers or slices") # Create a new matrix of the correct dimensions first = seq[0] last = seq[-1] if first < 0 or first >= self.shape[1] or last < 0 \ or last >= self.shape[1]: raise IndexError("index out of bounds") newshape = (1, last - first + 1) new = dok_matrix(newshape) # ** This uses linear time in the size n of dimension 1: # new[0, 0:seq[-1]-seq[0]+1] = \ # [self.get((i, element), 0) for element in seq] # ** Instead loop over the non-zero elements. This is slower # ** if there are many non-zeros for (ii, jj) in self.keys(): if ii == i and jj >= first and jj <= last: dict.__setitem__(new, (0, jj-first), \ dict.__getitem__(self, (ii,jj))) return new
def __getitem__(self, key): def asindices(x): try: x = np.asarray(x, dtype=np.intc) except: raise IndexError('invalid index') else: return x def check_bounds(indices,N): max_indx = indices.max() if max_indx >= N: raise IndexError('index (%d) out of range' % max_indx) min_indx = indices.min() if min_indx < -N: raise IndexError('index (%d) out of range' % (N + min_indx)) return (min_indx,max_indx) def extractor(indices,N): """Return a sparse matrix P so that P*self implements slicing of the form self[[1,2,3],:] """ indices = asindices(indices) (min_indx,max_indx) = check_bounds(indices,N) if min_indx < 0: indices = indices.copy() indices[indices < 0] += N indptr = np.arange(len(indices) + 1, dtype=np.intc) data = np.ones(len(indices), dtype=self.dtype) shape = (len(indices),N) return csr_matrix((data,indices,indptr), shape=shape) if isinstance(key, tuple): row = key[0] col = key[1] if isintlike(row): #[1,??] if isintlike(col): return self._get_single_element(row, col) #[i,j] elif isinstance(col, slice): return self._get_row_slice(row, col) #[i,1:2] else: P = extractor(col,self.shape[1]).T #[i,[1,2]] return self[row,:]*P elif isinstance(row, slice): #[1:2,??] if isintlike(col) or isinstance(col, slice): return self._get_submatrix(row, col) #[1:2,j] else: P = extractor(col,self.shape[1]).T #[1:2,[1,2]] return self[row,:]*P else: #[[1,2],??] or [[[1],[2]],??] if isintlike(col) or isinstance(col,slice): P = extractor(row, self.shape[0]) #[[1,2],j] or [[1,2],1:2] return (P*self)[:,col] else: 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') check_bounds(row, self.shape[0]) check_bounds(col, self.shape[1]) num_samples = len(row) val = np.empty(num_samples, dtype=self.dtype) csr_sample_values(self.shape[0], self.shape[1], self.indptr, self.indices, self.data, num_samples, row, col, val) #val = [] #for i,j in zip(row,col): # val.append(self._get_single_element(i,j)) return np.asmatrix(val) elif len(row.shape) == 2: row = np.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: return self[asindices(key),:] #[[1,2]]