def todok(self): from .dok import dok_matrix dok = dok_matrix((self.shape), dtype=self.dtype) dok.update(izip(izip(self.row,self.col),self.data)) return dok
def todok(self): from .dok import dok_matrix dok = dok_matrix((self.shape), dtype=self.dtype) dok.update(izip(izip(self.row, self.col), self.data)) return dok
def __setitem__(self, index, x): if isinstance(index, tuple) and len(index) == 2: # Integer index fast path i, j = index if (isintlike(i) and isintlike(j) and 0 <= i < self.shape[0] and 0 <= j < self.shape[1]): v = np.asarray(x, dtype=self.dtype) if v.ndim == 0 and v != 0: dict.__setitem__(self, (int(i), int(j)), v[()]) return i, j = self._unpack_index(index) i, j = self._index_to_arrays(i, j) if isspmatrix(x): x = x.toarray() # Make x and i into the same shape x = np.asarray(x, dtype=self.dtype) x, _ = np.broadcast_arrays(x, i) if x.shape != i.shape: raise ValueError("shape mismatch in assignment") if np.size(x) == 0: return min_i = i.min() if min_i < -self.shape[0] or i.max() >= self.shape[0]: raise IndexError('index (%d) out of range -%d to %d)' % (i.min(), self.shape[0], self.shape[0] - 1)) if min_i < 0: i = i.copy() i[i < 0] += self.shape[0] min_j = j.min() if min_j < -self.shape[0] or j.max() >= self.shape[1]: raise IndexError('index (%d) out of range -%d to %d)' % (j.min(), self.shape[1], self.shape[1] - 1)) if min_j < 0: j = j.copy() j[j < 0] += self.shape[1] dict.update(self, izip(izip(i.flat, j.flat), x.flat)) if 0 in x: zeroes = x == 0 for key in izip(i[zeroes].flat, j[zeroes].flat): if dict.__getitem__(self, key) == 0: # may have been superseded by later update del self[key]
def __setitem__(self, index, x): if isinstance(index, tuple) and len(index) == 2: # Integer index fast path i, j = index if (isintlike(i) and isintlike(j) and 0 <= i < self.shape[0] and 0 <= j < self.shape[1]): v = np.asarray(x, dtype=self.dtype) if v.ndim == 0 and v != 0: dict.__setitem__(self, (int(i), int(j)), v[()]) return i, j = self._unpack_index(index) i, j = self._index_to_arrays(i, j) if isspmatrix(x): x = x.toarray() # Make x and i into the same shape x = np.asarray(x, dtype=self.dtype) x, _ = np.broadcast_arrays(x, i) if x.shape != i.shape: raise ValueError("shape mismatch in assignment") if np.size(x) == 0: return min_i = i.min() if min_i < -self.shape[0] or i.max() >= self.shape[0]: raise IndexError('index (%d) out of range -%d to %d)' % (i.min(), self.shape[0], self.shape[0]-1)) if min_i < 0: i = i.copy() i[i < 0] += self.shape[0] min_j = j.min() if min_j < -self.shape[0] or j.max() >= self.shape[1]: raise IndexError('index (%d) out of range -%d to %d)' % (j.min(), self.shape[1], self.shape[1]-1)) if min_j < 0: j = j.copy() j[j < 0] += self.shape[1] dict.update(self, izip(izip(i.flat, j.flat), x.flat)) if 0 in x: zeroes = x == 0 for key in izip(i[zeroes].flat, j[zeroes].flat): if dict.__getitem__(self, key) == 0: # may have been superseded by later update del self[key]
def _insert_many(self, i, j, x): """Inserts new nonzero at each (i, j) with value x Here (i,j) index major and minor respectively. i, j and x must be non-empty, 1d arrays. Inserts each major group (e.g. all entries per row) at a time. Maintains has_sorted_indices property. Modifies i, j, x in place. """ order = np.argsort(i, kind='mergesort') # stable for duplicates i = i.take(order, mode='clip') j = j.take(order, mode='clip') x = x.take(order, mode='clip') do_sort = self.has_sorted_indices # Update index data type idx_dtype = get_index_dtype((self.indices, self.indptr), maxval=(self.indptr[-1] + x.size)) if idx_dtype != self.indptr.dtype: self.indptr = self.indptr.astype(idx_dtype) self.indices = self.indices.astype(idx_dtype) if idx_dtype != i.dtype or idx_dtype != j.dtype: i = i.astype(idx_dtype) j = j.astype(idx_dtype) # Collate old and new in chunks by major index indices_parts = [] data_parts = [] ui, ui_indptr = np.unique(i, return_index=True) ui_indptr = np.append(ui_indptr, len(j)) new_nnzs = np.diff(ui_indptr) prev = 0 for c, (ii, js, je) in enumerate(izip(ui, ui_indptr, ui_indptr[1:])): # old entries start = self.indptr[prev] stop = self.indptr[ii] indices_parts.append(self.indices[start:stop]) data_parts.append(self.data[start:stop]) # handle duplicate j: keep last setting uj, uj_indptr = np.unique(j[js:je][::-1], return_index=True) if len(uj) == je - js: indices_parts.append(j[js:je]) data_parts.append(x[js:je]) else: indices_parts.append(j[js:je][::-1][uj_indptr]) data_parts.append(x[js:je][::-1][uj_indptr]) new_nnzs[c] = len(uj) prev = ii # remaining old entries start = self.indptr[ii] indices_parts.append(self.indices[start:]) data_parts.append(self.data[start:]) # update attributes self.indices = np.concatenate(indices_parts) self.data = np.concatenate(data_parts) nnzs = np.ediff1d(self.indptr, to_begin=0).astype(idx_dtype) nnzs[1:][ui] += new_nnzs self.indptr = np.cumsum(nnzs, out=nnzs) if do_sort: # TODO: only sort where necessary self.sort_indices() self.check_format(full_check=False)
def _insert_many(self, i, j, x): """Inserts new nonzero at each (i, j) with value x Here (i,j) index major and minor respectively. i, j and x must be non-empty, 1d arrays. Inserts each major group (e.g. all entries per row) at a time. Maintains has_sorted_indices property. Modifies i, j, x in place. """ order = np.argsort(i, kind="mergesort") # stable for duplicates i = i.take(order, mode="clip") j = j.take(order, mode="clip") x = x.take(order, mode="clip") do_sort = self.has_sorted_indices # Update index data type idx_dtype = get_index_dtype((self.indices, self.indptr), maxval=(self.indptr[-1] + x.size)) if idx_dtype != self.indptr.dtype: self.indptr = self.indptr.astype(idx_dtype) self.indices = self.indices.astype(idx_dtype) if idx_dtype != i.dtype or idx_dtype != j.dtype: i = i.astype(idx_dtype) j = j.astype(idx_dtype) # Collate old and new in chunks by major index indices_parts = [] data_parts = [] ui, ui_indptr = _compat_unique(i, return_index=True) ui_indptr = np.append(ui_indptr, len(j)) new_nnzs = np.diff(ui_indptr) prev = 0 for c, (ii, js, je) in enumerate(izip(ui, ui_indptr, ui_indptr[1:])): # old entries start = self.indptr[prev] stop = self.indptr[ii] indices_parts.append(self.indices[start:stop]) data_parts.append(self.data[start:stop]) # handle duplicate j: keep last setting uj, uj_indptr = _compat_unique(j[js:je][::-1], return_index=True) if len(uj) == je - js: indices_parts.append(j[js:je]) data_parts.append(x[js:je]) else: indices_parts.append(j[js:je][::-1][uj_indptr]) data_parts.append(x[js:je][::-1][uj_indptr]) new_nnzs[c] = len(uj) prev = ii # remaining old entries start = self.indptr[ii] indices_parts.append(self.indices[start:]) data_parts.append(self.data[start:]) # update attributes self.indices = np.concatenate(indices_parts) self.data = np.concatenate(data_parts) nnzs = np.ediff1d(self.indptr, to_begin=0).astype(idx_dtype) nnzs[1:][ui] += new_nnzs self.indptr = np.cumsum(nnzs, out=nnzs) if do_sort: # TODO: only sort where necessary self.sort_indices() self.check_format(full_check=False)
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 (i,j) in self: 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): seq = xrange(*i.indices(self.shape[0])) 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.indices(self.shape[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 __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 (i, j) in self: 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