Coverage for /usr/lib/python3/dist-packages/scipy/sparse/_csc.py: 39%

90 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-06-14 15:25 +0200

1"""Compressed Sparse Column matrix format""" 

2__docformat__ = "restructuredtext en" 

3 

4__all__ = ['csc_array', 'csc_matrix', 'isspmatrix_csc'] 

5 

6 

7import numpy as np 

8 

9from ._matrix import spmatrix, _array_doc_to_matrix 

10from ._base import _spbase, sparray 

11from ._sparsetools import csc_tocsr, expandptr 

12from ._sputils import upcast 

13 

14from ._compressed import _cs_matrix 

15 

16 

17class _csc_base(_cs_matrix): 

18 """ 

19 Compressed Sparse Column matrix 

20 

21 This can be instantiated in several ways: 

22 

23 csc_array(D) 

24 with a dense matrix or rank-2 ndarray D 

25 

26 csc_array(S) 

27 with another sparse matrix S (equivalent to S.tocsc()) 

28 

29 csc_array((M, N), [dtype]) 

30 to construct an empty matrix with shape (M, N) 

31 dtype is optional, defaulting to dtype='d'. 

32 

33 csc_array((data, (row_ind, col_ind)), [shape=(M, N)]) 

34 where ``data``, ``row_ind`` and ``col_ind`` satisfy the 

35 relationship ``a[row_ind[k], col_ind[k]] = data[k]``. 

36 

37 csc_array((data, indices, indptr), [shape=(M, N)]) 

38 is the standard CSC representation where the row indices for 

39 column i are stored in ``indices[indptr[i]:indptr[i+1]]`` 

40 and their corresponding values are stored in 

41 ``data[indptr[i]:indptr[i+1]]``. If the shape parameter is 

42 not supplied, the matrix dimensions are inferred from 

43 the index arrays. 

44 

45 Attributes 

46 ---------- 

47 dtype : dtype 

48 Data type of the matrix 

49 shape : 2-tuple 

50 Shape of the matrix 

51 ndim : int 

52 Number of dimensions (this is always 2) 

53 nnz 

54 Number of stored values, including explicit zeros 

55 data 

56 Data array of the matrix 

57 indices 

58 CSC format index array 

59 indptr 

60 CSC format index pointer array 

61 has_sorted_indices 

62 Whether indices are sorted 

63 

64 Notes 

65 ----- 

66 

67 Sparse matrices can be used in arithmetic operations: they support 

68 addition, subtraction, multiplication, division, and matrix power. 

69 

70 Advantages of the CSC format 

71 - efficient arithmetic operations CSC + CSC, CSC * CSC, etc. 

72 - efficient column slicing 

73 - fast matrix vector products (CSR, BSR may be faster) 

74 

75 Disadvantages of the CSC format 

76 - slow row slicing operations (consider CSR) 

77 - changes to the sparsity structure are expensive (consider LIL or DOK) 

78 

79 Canonical format 

80 - Within each column, indices are sorted by row. 

81 - There are no duplicate entries. 

82 

83 Examples 

84 -------- 

85 

86 >>> import numpy as np 

87 >>> from scipy.sparse import csc_array 

88 >>> csc_array((3, 4), dtype=np.int8).toarray() 

89 array([[0, 0, 0, 0], 

90 [0, 0, 0, 0], 

91 [0, 0, 0, 0]], dtype=int8) 

92 

93 >>> row = np.array([0, 2, 2, 0, 1, 2]) 

94 >>> col = np.array([0, 0, 1, 2, 2, 2]) 

95 >>> data = np.array([1, 2, 3, 4, 5, 6]) 

96 >>> csc_array((data, (row, col)), shape=(3, 3)).toarray() 

97 array([[1, 0, 4], 

98 [0, 0, 5], 

99 [2, 3, 6]]) 

100 

101 >>> indptr = np.array([0, 2, 3, 6]) 

102 >>> indices = np.array([0, 2, 2, 0, 1, 2]) 

103 >>> data = np.array([1, 2, 3, 4, 5, 6]) 

104 >>> csc_array((data, indices, indptr), shape=(3, 3)).toarray() 

105 array([[1, 0, 4], 

106 [0, 0, 5], 

107 [2, 3, 6]]) 

108 

109 """ 

110 _format = 'csc' 

111 

112 def transpose(self, axes=None, copy=False): 

113 if axes is not None: 

114 raise ValueError("Sparse matrices do not support " 

115 "an 'axes' parameter because swapping " 

116 "dimensions is the only logical permutation.") 

117 

118 M, N = self.shape 

119 

120 return self._csr_container((self.data, self.indices, 

121 self.indptr), (N, M), copy=copy) 

122 

123 transpose.__doc__ = _spbase.transpose.__doc__ 

124 

125 def __iter__(self): 

126 yield from self.tocsr() 

127 

128 def tocsc(self, copy=False): 

129 if copy: 

130 return self.copy() 

131 else: 

132 return self 

133 

134 tocsc.__doc__ = _spbase.tocsc.__doc__ 

135 

136 def tocsr(self, copy=False): 

137 M,N = self.shape 

138 idx_dtype = self._get_index_dtype((self.indptr, self.indices), 

139 maxval=max(self.nnz, N)) 

140 indptr = np.empty(M + 1, dtype=idx_dtype) 

141 indices = np.empty(self.nnz, dtype=idx_dtype) 

142 data = np.empty(self.nnz, dtype=upcast(self.dtype)) 

143 

144 csc_tocsr(M, N, 

145 self.indptr.astype(idx_dtype), 

146 self.indices.astype(idx_dtype), 

147 self.data, 

148 indptr, 

149 indices, 

150 data) 

151 

152 A = self._csr_container( 

153 (data, indices, indptr), 

154 shape=self.shape, copy=False 

155 ) 

156 A.has_sorted_indices = True 

157 return A 

158 

159 tocsr.__doc__ = _spbase.tocsr.__doc__ 

160 

161 def nonzero(self): 

162 # CSC can't use _cs_matrix's .nonzero method because it 

163 # returns the indices sorted for self transposed. 

164 

165 # Get row and col indices, from _cs_matrix.tocoo 

166 major_dim, minor_dim = self._swap(self.shape) 

167 minor_indices = self.indices 

168 major_indices = np.empty(len(minor_indices), dtype=self.indices.dtype) 

169 expandptr(major_dim, self.indptr, major_indices) 

170 row, col = self._swap((major_indices, minor_indices)) 

171 

172 # Remove explicit zeros 

173 nz_mask = self.data != 0 

174 row = row[nz_mask] 

175 col = col[nz_mask] 

176 

177 # Sort them to be in C-style order 

178 ind = np.argsort(row, kind='mergesort') 

179 row = row[ind] 

180 col = col[ind] 

181 

182 return row, col 

183 

184 nonzero.__doc__ = _cs_matrix.nonzero.__doc__ 

185 

186 def _getrow(self, i): 

187 """Returns a copy of row i of the matrix, as a (1 x n) 

188 CSR matrix (row vector). 

189 """ 

190 M, N = self.shape 

191 i = int(i) 

192 if i < 0: 

193 i += M 

194 if i < 0 or i >= M: 

195 raise IndexError('index (%d) out of range' % i) 

196 return self._get_submatrix(minor=i).tocsr() 

197 

198 def _getcol(self, i): 

199 """Returns a copy of column i of the matrix, as a (m x 1) 

200 CSC matrix (column vector). 

201 """ 

202 M, N = self.shape 

203 i = int(i) 

204 if i < 0: 

205 i += N 

206 if i < 0 or i >= N: 

207 raise IndexError('index (%d) out of range' % i) 

208 return self._get_submatrix(major=i, copy=True) 

209 

210 def _get_intXarray(self, row, col): 

211 return self._major_index_fancy(col)._get_submatrix(minor=row) 

212 

213 def _get_intXslice(self, row, col): 

214 if col.step in (1, None): 

215 return self._get_submatrix(major=col, minor=row, copy=True) 

216 return self._major_slice(col)._get_submatrix(minor=row) 

217 

218 def _get_sliceXint(self, row, col): 

219 if row.step in (1, None): 

220 return self._get_submatrix(major=col, minor=row, copy=True) 

221 return self._get_submatrix(major=col)._minor_slice(row) 

222 

223 def _get_sliceXarray(self, row, col): 

224 return self._major_index_fancy(col)._minor_slice(row) 

225 

226 def _get_arrayXint(self, row, col): 

227 return self._get_submatrix(major=col)._minor_index_fancy(row) 

228 

229 def _get_arrayXslice(self, row, col): 

230 return self._major_slice(col)._minor_index_fancy(row) 

231 

232 # these functions are used by the parent class (_cs_matrix) 

233 # to remove redudancy between csc_array and csr_matrix 

234 def _swap(self, x): 

235 """swap the members of x if this is a column-oriented matrix 

236 """ 

237 return x[1], x[0] 

238 

239 

240def isspmatrix_csc(x): 

241 """Is `x` of csc_matrix type? 

242 

243 Parameters 

244 ---------- 

245 x 

246 object to check for being a csc matrix 

247 

248 Returns 

249 ------- 

250 bool 

251 True if `x` is a csc matrix, False otherwise 

252 

253 Examples 

254 -------- 

255 >>> from scipy.sparse import csc_array, csc_matrix, coo_matrix, isspmatrix_csc 

256 >>> isspmatrix_csc(csc_matrix([[5]])) 

257 True 

258 >>> isspmatrix_csc(csc_array([[5]])) 

259 False 

260 >>> isspmatrix_csc(coo_matrix([[5]])) 

261 False 

262 """ 

263 return isinstance(x, csc_matrix) 

264 

265 

266# This namespace class separates array from matrix with isinstance 

267class csc_array(_csc_base, sparray): 

268 pass 

269 

270csc_array.__doc__ = _csc_base.__doc__ 

271 

272class csc_matrix(spmatrix, _csc_base): 

273 pass 

274 

275csc_matrix.__doc__ = _array_doc_to_matrix(_csc_base.__doc__)