在numpy reshape 中表示更改shape 以保持相同的数字元素。所以形状项的乘积不能改变。
最简单的例子是这样的
np.arange(12).reshape(3,4)
赋值方法是:
x = np.arange(12)
x.shape = (3,4)
method(或np.reshape(...))返回一个新数组。 shape 分配工作在原地。
您引用的文档说明在执行类似操作时会发挥作用
x = np.arange(12).reshape(3,4).T
x.reshape(3,4) # ok, but copy
x.shape = (3,4) # raises error
为了更好地了解这里发生的情况,请在不同阶段打印数组,并查看原始 0,1,2,... 连续性如何变化。 (这留给读者作为练习,因为它不是更大问题的核心。)
有一个resize 函数和方法,但用得不多,而且它在视图和副本方面的行为很棘手。
np.concatenate(以及np.stack、np.vstack 等变体)创建新数组,并从输入中复制所有数据。
列表(和对象 dtype 数组)包含指向元素(可能是数组)的指针,因此不需要复制数据。
稀疏矩阵将其数据(和行/列索引)存储在不同格式的各种属性中。 coo、csr 和 csc 有 3 个一维数组。 lil 有 2 个包含列表的对象数组。 dok 是一个字典子类。
lil_matrix 实现了一个reshape 方法。其他格式没有。与np.reshape 一样,维度的乘积不能改变。
理论上,稀疏矩阵可以“嵌入”到更大的矩阵中,而数据复制最少,因为所有新值都将是默认值 0,并且不占用任何空间。但该操作的细节尚未针对任何格式制定。
sparse.hstack 和sparse.vstack(不要在稀疏矩阵上使用numpy 版本)通过组合输入的coo 属性(通过sparse.bmat)工作。所以是的,他们制作了新数组(data、row、col)。
制作更大稀疏矩阵的最小示例:
In [110]: M = sparse.random(5,5,.2,'coo')
In [111]: M
Out[111]:
<5x5 sparse matrix of type '<class 'numpy.float64'>'
with 5 stored elements in COOrdinate format>
In [112]: M.A
Out[112]:
array([[0. , 0.80957797, 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0.23618044, 0. , 0.91625967, 0.8791744 ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0.7928235 , 0. ]])
In [113]: M1 = sparse.coo_matrix((M.data, (M.row, M.col)),shape=(7,5))
In [114]: M1
Out[114]:
<7x5 sparse matrix of type '<class 'numpy.float64'>'
with 5 stored elements in COOrdinate format>
In [115]: M1.A
Out[115]:
array([[0. , 0.80957797, 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0.23618044, 0. , 0.91625967, 0.8791744 ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0.7928235 , 0. ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0. ]])
In [116]: id(M1.data)
Out[116]: 139883362735488
In [117]: id(M.data)
Out[117]: 139883362735488
M 和 M1 具有相同的 data 属性(相同的数组 ID)。但是对这些矩阵的大多数操作都需要转换为另一种格式(例如csr 用于数学,或lil 用于更改值),并且将涉及复制和修改属性。所以这两个矩阵之间的联系将被打破。
当您使用coo_matrix 之类的函数创建稀疏矩阵并且不提供shape 参数时,它会根据提供的坐标推断形状。如果您提供 shape 它会使用它。该形状必须至少与隐含形状一样大。使用lil(和dok),您可以有利地创建一个具有大形状的“空”矩阵,然后迭代地设置值。你不想用csr 这样做。并且不能直接设置coo 值。
创建稀疏矩阵的规范方法是构建 data、row 和 col 数组或从各个部分迭代地列出 - 使用列表追加/扩展或数组连接,并创建一个 coo (或csr) 格式数组。所以你甚至在创建矩阵之前就完成了所有的“增长”。
改变_shape
制作一个矩阵:
In [140]: M = (sparse.random(5,3,.4,'csr')*10).astype(int)
In [141]: M
Out[141]:
<5x3 sparse matrix of type '<class 'numpy.int64'>'
with 6 stored elements in Compressed Sparse Row format>
In [142]: M.A
Out[142]:
array([[0, 6, 7],
[0, 0, 6],
[1, 0, 5],
[0, 0, 0],
[0, 6, 0]])
In [144]: M[1,0] = 10
... SparseEfficiencyWarning)
In [145]: M.A
Out[145]:
array([[ 0, 6, 7],
[10, 0, 6],
[ 1, 0, 5],
[ 0, 0, 0],
[ 0, 6, 0]])
你的新形状方法(确保indptr 的dtype 不会改变):
In [146]: M._shape = (6,3)
In [147]: newptr = np.hstack((M.indptr,M.indptr[-1]))
In [148]: newptr
Out[148]: array([0, 2, 4, 6, 6, 7, 7], dtype=int32)
In [149]: M.indptr = newptr
In [150]: M
Out[150]:
<6x3 sparse matrix of type '<class 'numpy.int64'>'
with 7 stored elements in Compressed Sparse Row format>
In [151]: M.A
Out[151]:
array([[ 0, 6, 7],
[10, 0, 6],
[ 1, 0, 5],
[ 0, 0, 0],
[ 0, 6, 0],
[ 0, 0, 0]])
In [152]: M[5,2]=10
... SparseEfficiencyWarning)
In [153]: M.A
Out[153]:
array([[ 0, 6, 7],
[10, 0, 6],
[ 1, 0, 5],
[ 0, 0, 0],
[ 0, 6, 0],
[ 0, 0, 10]])
添加一列似乎也可以:
In [154]: M._shape = (6,4)
In [155]: M
Out[155]:
<6x4 sparse matrix of type '<class 'numpy.int64'>'
with 8 stored elements in Compressed Sparse Row format>
In [156]: M.A
Out[156]:
array([[ 0, 6, 7, 0],
[10, 0, 6, 0],
[ 1, 0, 5, 0],
[ 0, 0, 0, 0],
[ 0, 6, 0, 0],
[ 0, 0, 10, 0]])
In [157]: M[5,0]=10
.... SparseEfficiencyWarning)
In [158]: M[5,3]=10
.... SparseEfficiencyWarning)
In [159]: M
Out[159]:
<6x4 sparse matrix of type '<class 'numpy.int64'>'
with 10 stored elements in Compressed Sparse Row format>
In [160]: M.A
Out[160]:
array([[ 0, 6, 7, 0],
[10, 0, 6, 0],
[ 1, 0, 5, 0],
[ 0, 0, 0, 0],
[ 0, 6, 0, 0],
[10, 0, 10, 10]])
属性分享
我可以从现有矩阵中创建一个新矩阵:
In [108]: M = (sparse.random(5,3,.4,'csr')*10).astype(int)
In [109]: newptr = np.hstack((M.indptr,6))
In [110]: M1 = sparse.csr_matrix((M.data, M.indices, newptr), shape=(6,3))
data 属性是共享的,至少在视图意义上:
In [113]: M[0,1]=14
In [114]: M1[0,1]
Out[114]: 14
但如果我通过添加一个非零值来修改M1:
In [117]: M1[5,0]=10
...
SparseEfficiencyWarning)
矩阵之间的链接断开:
In [120]: M[0,1]=3
In [121]: M1[0,1]
Out[121]: 14