我想要创建一个矩阵,其中第(i,j)个条目是某个有序列表L的元素i:j的总和。我实际上想要停止在总和超过L的最大成员的基元中
例如,如果L = [2,3,5,7]
,矩阵将如下所示:
[ 2, 5, 0, 0 ]
[ 0, 3, 0, 0 ]
[ 0, 0, 5, 0 ]
[ 0, 0, 0, 7 ]
然后我想扫描矩阵并找到列表中连接到列表中另一个元素的最大连续成员数,如果有多个这些子列表,那么我选择最高的那个和。所以在我之前的例子中,最高的数字是2,因为2 + 5 = 7和7在列表中。
对于非常大的列表,最快的方法是什么? (数百万元素)。我可以做类似的事情:
m = np.zeros(shape = (nmb, nmb))
for i in range(0, nmb):
m[i, i:] = np.cumsum(L[i:])
print(m)
但是我不确定当超过L的最高值时如何停止cumsum。事实上,我真的只需要矩阵的上三角形,或者实际上只需要主对角线和一些上三角形对角线,因为累积和超过L中的最高值要比耗尽矩阵中的列数更早。
更新:
快一点:
m = np.zeros(shape = (nmb, nmb))
np.fill_diagonal(m, L)
for i in range(0, nmb):
j = i + 1
while 2*m[i,j-1]<L[-1]:
m[i, j] = m[i, j-1] + m[j, j]
j+=1
print(m)
似乎仍然很慢过滤并挑选出最大的条纹,也许我不应该使用有这么多零的矩阵
答案 0 :(得分:1)
好的,所以我一直走到10,000个元素(更多的开始接近内存限制然后是速度本身的问题)并且我发现这相当快(在我的机器上不到1秒)< / p>
import numpy as np
import time
Cl1 = time.time()
L = np.random.randint(1,100,10000)
nmb = np.size(L)
m = np.zeros(shape = (nmb, nmb))
np.fill_diagonal(m, L)
for i in range(nmb-1):
j = i+1
if np.sum(L[i:j+1])<=np.max(L):
m[i,j] = np.sum(L[i:j+1])
Cl2 = time.time()
print(m)
print(Cl2-Cl1)