如何加快3个连续for循环的速度,将数据定位到新的矩阵中

2024-05-16 11:05:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从experiment创建新的矩阵experiment2experiment的维数是13500*12000。我想对每10列求和(但保留行号)以减少维数。你知道吗

第一组是列索引之和0-9, 10-19, 20-29..., 13490-13449

第二组是列索引的和5-14, 15-24, 25-34...,13485-13494

将第一组输入偶数索引,第二组输入experiment2的奇数索引。新矩阵减少到13500*2400

我在这里用3个for循环来表示每一组,速度非常慢。怎么在这里跑得更快?你知道吗

window = 10

experiment2 = np.zeros(shape=(13500,2400))
for eachrow in range(13500):
    for unit in range(1200):
        for even in range(0, (2400), 2):
            # each row, sum column 0-9, 10-19,... and input to experiment2 at even
            experiment2[eachrow, even] = sum(experiment[eachrow,:][(10*unit):((10*unit)+10)])

for eachrow in range(13500):
    for unit in range(1200):
        for odd in range(1, (2400), 2):
            # each row, sum column 5-14, 15-24,... and input to experiment2 at odd
            experiment2[eachrow, odd] = sum(experiment[eachrow,:][((10*unit)+5):((10*unit)+10+5)])

Tags: inforunitrangecolumn矩阵rowexperiment
2条回答

如果你想一想,你必须循环所有13500*12000项至少一次,以计算总和。你不能低于这个值,所以你应该尝试在13500*12000次迭代中求解它。这意味着,您应该只迭代原始数组中的项,并且只迭代一次。你知道吗

为了计算和,应该避免使用会再次迭代的东西,所以不要使用sum。相反,您可以直接添加到目标数组中,因为它是使用np.zeros初始化为零的。你知道吗

experiment2 = np.zeros(shape=(13500,2400))
for row in range(13500):
    for col in range(12000):
        # calculate the target indexes for `experiment2`. To keep the complexity
        # linear to the original array size, this has to be done in constant time
        # using only the indexes we have
        evenIndex = (col / 10) * 2
        oddIndex = ((col + 5) / 10 ) * 2 - 1

        # add the numbers
        expirement2[row, evenIndex] += expirement[row, col]

        # only add odd if we’re past 4 though, and before 11995
        if 4 < col < 11995:
             expirement2[row, oddIndex] += expirement[row, col]

这将在O(N)中工作,因为N是输入数组的总大小,只进行一次迭代。如前所述,如果要查看所有数字,就不能低于此值。你知道吗

请注意,此解决方案保留了一个奇数数组索引:expirement[row, 2399],因为这是最后一个,并且只获取列索引1199511996119971199811999。我不知道您在这里的用例,但是您可以用值01234来填充它,这些值也被忽略了。不过,您必须在上面显式地处理这个问题(只需添加一个else案例)。你知道吗

我不是一个裸体专家,但我会这样写:

experiment2 = np.zeros(shape=(13500,2400))
xeven, yeven, xodd, yodd = 0, 10, 5, 15

for eachrow in xrange(13500):
    for unit in xrange(1200):
        sumeven = sum(experiment[eachrow,:][xeven:yeven])
        sumodd = sum(experiment[eachrow,:][xodd:yodd])

        for even in xrange(0, 2400, 2):
            experiment2[eachrow, even] = sumeven
            experiment2[eachrow, even + 1] = sumodd

        xeven += 10
        yeven += 10
        xodd += 10
        yodd += 10

其思想是在同一个循环中填充奇数列和偶数列。另一件事,为了避免计算10*unit+...1200次,我将它们存储在xeven, yeven, xodd, yodd中并递增。 我还使用xrange返回一个迭代器(因为您使用的是python2.7),而不是range返回一个列表。你知道吗

相关问题 更多 >