【问题标题】:PYTHON - finding the maximum of every 10 integers in an arrayPYTHON - 查找数组中每 10 个整数的最大值
【发布时间】:2018-01-08 21:07:48
【问题描述】:

我有一个大整数数组,我需要将每 10 个整数的最大值及其在数组中的对应索引作为一对打印出来。

ex. (max_value, index of max_value in array)

我可以在前 10 个整数中成功找到最大值和对应的索引,但是我在循环整个数组时遇到了麻烦。

我尝试过使用:

a = some array of integers

split = [a[i:i+10] for i in xrange(0, len(a), 10)] 

for i in split:
    j = max(i) 
    k = i.index(max(i))
    print (j,k)

这种方法的问题在于它将我的数组分成 10 个块,因此 max_values 是正确的,但索引不准确(所有索引都在 0-10 之间。) 我需要找到一种不会将我的数组拆分成块的方法,以便保留原始索引。我确信有一种更简单的方法可以循环查找最大值,但我似乎无法弄清楚。

【问题讨论】:

  • 数组中是否有重复值?
  • 如果您添加了enumerate,则可以计算索引,然后执行q*10+i,其中 q 是枚举计数器

标签: python arrays python-2.x xrange


【解决方案1】:

对您当前代码的小修改:

a = some array of integers

split = [a[i:i+10] for i in xrange(0, len(a), 10)] 

for index, i in enumerate(split):
    j = max(i) 
    k = i.index(max(i))
    print (j, k+10*index)

【讨论】:

  • 似乎每个人都想计算两次j,每次我都会畏缩一下:P(反正不会有真正的影响......)
  • 微优化老兄!但是,是的,您应该在生产场景中重新使用j。不过,在 Stack Overflow 上,一切都是为了清晰和熟悉。 :)
【解决方案2】:

您需要计算出现在当前窗口之前的元素数量。这将完成这项工作:

a=list(range(5,35))
split = [a[i:i+10] for i in xrange(0, len(a), 10)] 

for ind,i in enumerate(split):
    j = max(i) 
    k = i.index(j)
    print (j,k+ind*10)

打印出来

(14, 9)
(24, 19)
(34, 29)

【讨论】:

    【解决方案3】:

    所以通过一个示例数组进行调试,我们发现split 返回一个像这样的二维列表:

    [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]
    

    每次for 循环运行时,它都会按顺序遍历这些列表之一。首先它通过第一个内部列表,然后是第二个,依此类推。所以每次for 循环跳到下一个列表时,我们只需添加 10。由于列表中可以有超过 2 个列表,我们存储我们需要的数字添加一个变量并在每个循环中添加 10:

    a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
    split = [a[i:i+10] for i in xrange(0, len(a), 10)] 
    counter = 0
    
    for i in split:
        j = max(i) 
        k = i.index(max(i))
        print (j,k+counter)
        counter += 10
    

    你可以test it here

    【讨论】:

      【解决方案4】:

      toolz 包有一个 partition_all 函数,可以将一个序列分成大小相等的元组,所以你可以这样做。

      import toolz
      ns = list(range(25))
      [max(sublist) for sublist in toolz.partition_all(10, ns)]
      

      这将返回[9, 19, 24]。

      【讨论】:

        【解决方案5】:

        您需要循环遍历列表,但是我们可以更改您的 split 循环,使其更有效地满足您的需求。

        a = some array of integers
        
        split = [a[i:i+10] for i in xrange(0, len(a), 10)] 
        
        for i in range(len(split)):
            #Now instead of being the list, i is the index, so we can use 10*i as a counter
            j = max(split[i]) 
            #j = max(i) 
            k = split[i].index(j) + 10*i #replaced max(i) with j since we already calculated it.
            #k = i.index(max(i))
            print (j,k)
        

        尽管在未来,请为您的split 列表重新命名,因为split 已经是python 中的一个函数。可能是split_list 或separated 或其他一些看起来不像split() 函数的名称。

        【讨论】:

        • @dawg 没有名为 split.. 的函数,只有字符串的方法,所以没有跺脚。 whatever.split = something_else 会是个问题,但不是这个
        【解决方案6】:

        任意输入的numpy解决方案:

        import numpy as np
        
        a = np.random.randint(1,21,40)  #40 random numbers from 1 to 20
        
        b = a.reshape([4,10])  #shape into chunks 10 numbers long
        
        i = b.argsort()[:,-1]  #take the index of the largest number (last number from argsort) 
                               #  from each chunk. (these don't take into account the reshape)
        
        i += np.arange(0,40,10)  #add back in index offsets due to reshape
        
        out = zip(i, a[i])  #zip together indices and values
        

        【讨论】:

          【解决方案7】:

          您可以通过仅枚举一次并使用zip 将您的列表分成组来简化此操作:

          n=10
          for grp in zip(*[iter(enumerate(some_list))]*n):
              grp_max_ind, grp_mv=max(grp, key=lambda t: t[1])
              k=[t[1] for t in grp].index(grp_mv)
              print grp_mv, (grp_max_ind, k)
          

          如果您需要生成器,请在 Python 2 中使用 izip(或使用 Python 3)

          from itertools import izip 
          for grp in izip(*[iter(enumerate(some_list))]*n):
              grp_max_ind, grp_mv=max(grp, key=lambda t: t[1])
              k=[t[1] for t in grp].index(grp_mv)
              print grp_mv, (grp_max_ind, k)
          

          如果长度不是n,Zip 将截断最后一个组

          【讨论】:

            【解决方案8】:

            使用numpy 的示例。首先让我们生成一些数据,即从 1 到 V 和长度(值的数量)L 的整数:

            import numpy as np
            V = 1000
            L = 45 # method works with arrays not multiples of 10
            a = np.random.randint(1, V, size=L)
            

            现在解决大小为N的子数组的问题:

            import numpy as np
            N = 10 # example "split" size
            sa = np.array_split(a, range(N, len(a), N))
            sind = [np.argpartition(i, -1)[-1] for i in sa]
            ind = [np.ravel_multi_index(i, (len(sa), N)) for i in enumerate(sind)]
            vals = np.asarray(a)[np.asarray(ind)]
            split_imax = zip(vals, ind) # <-- output
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-08-15
              • 2015-07-04
              • 1970-01-01
              • 2015-10-30
              • 1970-01-01
              • 2018-08-27
              相关资源
              最近更新 更多