使用矩阵乘法,你可以做带高效切片创建与那些在正确的地方“切片”矩阵。切片矩阵与“切片器”具有相同的type
,因此您可以高效地控制输出类型。
下面你将看到一些比较和最有效的为您的情况是索要.A
矩阵和切它。它显示出比.toarray()
方法快得多。使用乘法是第二快的选项时,“限幅器”作为ndarray
,乘以csr
矩阵创建并切片的结果。
OBS:使用稀疏矩阵A
coo
导致稍慢定时,保持相同的比例,以及sol3
是不适用的,我后来意识到的是,在乘法它被自动转换为csr
。
import scipy
import scipy.sparse.csr as csr
test = csr.csr_matrix([
[11,12,13,14,15,16,17,18,19],
[21,22,23,24,25,26,27,28,29],
[31,32,33,34,35,36,37,38,39],
[41,42,43,44,45,46,47,48,49],
[51,52,53,54,55,56,57,58,59],
[61,62,63,64,65,66,67,68,69],
[71,72,73,74,75,76,77,78,79],
[81,82,83,84,85,86,88,88,89],
[91,92,93,94,95,96,99,98,99]])
def sol1():
B = test.A[2:5]
def sol2():
slicer = scipy.array([[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0,0],
[0,0,0,1,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0]])
B = (slicer*test)[2:]
return B
def sol3():
B = (test[2:5]).A
return B
def sol4():
slicer = csr.csr_matrix(((1,1,1),((2,3,4),(2,3,4))), shape=(5,9))
B = ((slicer*test).A)[2:] # just changing when we do the slicing
return B
def sol5():
slicer = csr.csr_matrix(((1,1,1),((2,3,4),(2,3,4))), shape=(5,9))
B = ((slicer*test)[2:]).A
return B
timeit sol1()
#10000 loops, best of 3: 60.4 us per loop
timeit sol2()
#10000 loops, best of 3: 91.4 us per loop
timeit sol3()
#10000 loops, best of 3: 111 us per loop
timeit sol4()
#1000 loops, best of 3: 310 us per loop
timeit sol5()
#1000 loops, best of 3: 363 us per loop
编辑:答案已经更新由.A
更换.toarray()
,使更快的结果和现在最好的解决方案是放在顶部
我不觉得矩阵乘法做的是对的选择**最大**,可能是**总和**。你有没有考虑使用CSC格式,而不是支持列切片? – Jaime
我想不出一种在稀疏数组上快速执行此操作的方法。但是,即使一个'(9000,1000)'阵列可在我的系统中处理约'100个ms'做'行,COLS = sparse_mat.shape'然后'np.max(sparse_mat.toarray()。重塑(行//10,10,cols),axis = 1)'。 – Jaime
感谢您的意见,在我的情况下,它需要几秒钟,因为矩阵要大得多。但是我将一些先前的知识放入,你没有:行数超过列的数量,因此我将循环遍历cols,重新塑形并计算最大值。这不是我想要的,但似乎没有什么更快。 –