【问题标题】:fastest way to find smallest sum of length n subsequences in python在python中找到长度n个子序列的最小总和的最快方法
【发布时间】:2017-08-29 11:27:32
【问题描述】:

给定一个列表L,找到所有连续长度n子序列的最快方法是什么,并找到最小和的索引。这是我的(慢)版本:

from random import randrange
import numpy as np
L = np.array([randrange(-5000, 5000) for _ in range(10 * 10**6)])   #random array
subarray_length = 3                                                 #for example
sublist_sums = [sum(L[i:i+subarray_length]) for i 
                         in range(0, len(L) - (subarray_length - 1))]

candidate_idx = 0
candidate_sum = sublist_sums[0]

for idx, val in enumerate(sublist_sums[1:]):
    if val < candidate_sum:
        candidate_sum, candidate_idx = val, idx + 1

print(candidate_idx)

MWE

L = [6,5,4,3,2,1]

# sublists: [[6,5,4], [5,4,3], [4,3,2], [3,2,1] ]

subarray_length = 3
sublist_sums = [sum(L[i:i+subarray_length]) for i 
                         in range(0, len(L) - (subarray_length - 1))]

# sublist_sums = [15, 12, 9, 6]

for idx, val in enumerate(sublist_sums[1:]):
    if val < candidate_sum:
        candidate_sum, candidate_idx = val, idx + 1

candidate_idx = 3  

# 3 is the index of the first element of the length 3 sublist 
# with the smallest sum of all 3 length consecutive sublists

【问题讨论】:

    标签: arrays performance list python-3.x numpy


    【解决方案1】:

    性能略低于@Divakar 的答案,您可以使用as_strided 收集子数组并从那里开始:

    import numpy as np
    
    def min_sub_sum(arr,n):
        shape = (arr.shape[0]-n+1,n)
        strides = arr.strides
        subs = np.lib.stride_tricks.as_strided(arr,shape,strides*2)
        sums = np.einsum('ij->i',subs)
        return np.argmin(sums)
    
    L = np.array([x for x in range(10000,0,-1)])
    n = 5
    
    print(min_sub_sum(L,n))
    # 9995
    

    【讨论】:

      【解决方案2】:

      这是一种方法 -

      # Based on http://stackoverflow.com/a/14314054/3293881 by @Jaime
      def moving_sum(a, n) :
          ret = np.cumsum(a)
          ret[n:] = ret[n:] - ret[:-n]
          return ret[n - 1:]
      
      sums = moving_sum(L, subarray_length)
      min_idx = sums.argmin()
      candidate_sum, candidate_idx = sums[min_idx], min_idx
      

      或者,我们可以使用np.convolve 来计算加窗求和,就像这样 -

      sums = np.convolve(L,np.ones(subarray_length,dtype=int),'valid')
      

      Scipy's uniform 1D filter 获取sums 的另一种方法-

      from scipy.ndimage.filters import uniform_filter1d as unif1d
      
      W = subarray_length
      a = np.array(L,dtype=float)
      
      hW = (W-1)//2
      sums = W*unif1d(a,size=W, mode='constant')[hW:-hW]
      

      【讨论】:

      • 哇,第一种方法太聪明了。 np.convolve 也很有用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 2016-03-07
      • 2013-11-20
      • 2014-11-12
      • 1970-01-01
      • 2015-03-08
      相关资源
      最近更新 更多