问题描述
因此,我需要将两个具有不同形状的csc
矩阵加在一起.矩阵如下所示:
So I have two csc
matrices of different shapes that I need to add together. The matrices look like this:
current_flows = (7005, 1001) 50.0
(8259, 1001) 65.0
(14007, 1001) 45.0
(9971, 1002) 80.0
: :
(69003, 211148) 0.0
result_flows = (7005, 1001) 40
(14007, 1001) 20
(9971, 1002) 35
: :
(71136, 71137) 90
final_flows = current_flows + result_flows
如某些行和列ID所示:(7005, 1001), (14007, 1001), (9971, 1002)
矩阵确实具有相同的元素.尽管它们的形状不同,但基于它们的最终行和列ID.
As illustrated by some of the row and column ID's shown: (7005, 1001), (14007, 1001), (9971, 1002)
the matrices do have elements in common. Based on their final row and column ID's though they are of different shape.
我想将两个矩阵加在一起,同时保留较大矩阵(current_flows
)的形状,并保持current_flows
的值相同,其中result_flows
没有匹配的行和列ID current_flows
.因此,即使result_flows
仅扩展到(71136, 71137)
I would like to add the two matrices together, while preserving the shape of the larger matrix (current_flows
) and keeping the values of current_flows
the same where result_flows
does not have a row and column ID that matches current_flows
. So, final_flows
will have row and column indexes extending to: (69003, 211148)
even though result_flows
only extends to (71136, 71137)
因此,我希望输出为:
final_flows = (7005, 1001) 90.0
(8259, 1001) 65.0
(14007, 1001) 65.0
(9971, 1002) 115.0
: :
(71136, 71137) 90
(69003, 211148) 0.0
让我知道您是否需要进一步的澄清,谢谢!
Let me know if you'd like any further clarification, thanks!
推荐答案
通过coo
定义矩阵或输入的coo样式(data,(row,col))
时,将对重复项进行求和.刚度矩阵的创建者(用于pde解)经常利用这一点.
When defining a matrix via coo
, or the coo style of input, (data,(row,col))
, duplicate entries are summed. Creators of stiffness matrices (for pde solutions) often take advantage of this.
这是使用该功能的函数.我将矩阵转换为coo
格式(如果需要),连接它们的属性,并建立一个新的矩阵.
This is a function that uses that. I convert the matrices to coo
format (if needed), concatenate their attributes, and build a new matrix.
def with_coo(x,y):
x=x.tocoo()
y=y.tocoo()
d = np.concatenate((x.data, y.data))
r = np.concatenate((x.row, y.row))
c = np.concatenate((x.col, y.col))
C = sparse.coo_matrix((d,(r,c)))
return C
以@Vadim的示例为例:
With @Vadim's examples:
In [59]: C_csc=current_flows.tocsc()
In [60]: R_csc=result_flows.tocsc()
In [61]: with_coo(C_csc, R_csc).tocsc().A
Out[61]:
array([[ 0, 0, 1],
[-1, 0, 4],
[ 0, -2, 0],
[ 3, 0, 0]], dtype=int32)
在进行计时时,我们必须要小心,因为格式转换是不平凡的,例如
When making timings we have to be careful because format conversion are nontrivial, e.g.
In [70]: timeit C_csc.tocoo()
10000 loops, best of 3: 128 µs per loop
In [71]: timeit C_csc.todok()
1000 loops, best of 3: 258 µs per loop
瓦迪姆的两个选择
def with_dok(x, y):
for k in y.keys(): # no has_key in py3
if k in x:
x[k] += y[k]
else:
x[k] = y[k]
return x
def with_update(x,y):
x.update((k, v+x.get(k)) for k, v in y.items())
return x
以csc
格式开始:
In [74]: timeit with_coo(C_csc,R_csc).tocsc()
1000 loops, best of 3: 629 µs per loop
In [76]: timeit with_update(C_csc.todok(),R_csc.todok()).tocsc()
1000 loops, best of 3: 1 ms per loop
In [77]: timeit with_dok(C_csc.todok(),R_csc.todok()).tocsc()
1000 loops, best of 3: 1.12 ms per loop
我想我的coo
方法会更好地扩展-但这只是一个猜测.
I'm guessing that my coo
approach will scale better - but that's just a guess at this point.
将转换排除在外,dok
更新看起来更好. y
只有2个项目,并且不进行任何复制-直接更改x
.
Taking conversions out of the picture, the dok
update looks better. y
has only 2 items, and it does not make any copies - it changes x
directly.
In [78]: %%timeit x=C_csc.todok(); y=R_csc.todok()
....: with_update(x, y)
....:
10000 loops, best of 3: 33.6 µs per loop
In [79]: %%timeit x=C_csc.tocoo(); y=R_csc.tocoo()
with_coo(x, y)
....:
10000 loops, best of 3: 138 µs per loop
================
================
dok_matrix
的__add__
方法包含(如果other
也是dok
).有评论想知道他们是否需要检查shape
.
The __add__
method for dok_matrix
contains (if other
is also dok
). There's a comment wondering whether they need to check shape
.
new = dok_matrix(self.shape, dtype=res_dtype)
new.update(self)
for key in other.keys():
new[key] += other[key]
[如果我先更改y
的形状,例如y._shape = x.shape
.这很麻烦,并且只能在原始形状的合理范围内使用.并且可能不会比with_update
方法快. dok
比csr
或csc
更适合这种形状更改.]
[I can get around the shape
check in x+y
if I first change the shape of y
, e.g. y._shape = x.shape
. This is kludgy and only works within rational limits of the original shapes. And might not be faster than the with_update
approach. dok
is more amenable to this sort of shape change than csr
or csc
.]
如果other
不是dok
,则显示self.tocsc()+other
.
对于匹配的形状,总和为
For matching shapes, the summation times are
In [91]: timeit current_flows+current_flows
1000 loops, best of 3: 413 µs per loop
In [92]: timeit C_csc+C_csc
1000 loops, best of 3: 223 µs per loop
这篇关于在python中添加两个形状不同的`csc`稀疏矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!