4

我有一个很大的整数数组,我需要将每 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 之间。)我需要找到一种方法来做到这一点t 将我的数组拆分为块,以便保留原始索引。我确信有一种更简单的方法可以循环查找最大值,但我似乎无法弄清楚。

4

8 回答 8

5

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

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)
于 2017-08-01T20:47:55.113 回答
5

对您当前代码的小修改:

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)
于 2017-08-01T20:50:16.213 回答
4

因此,通过使用示例数组进行调试,我们发现它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

你可以在这里测试

于 2017-08-01T20:46:17.777 回答
1

您将需要循环以遍历列表,但是我们可以更改您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_listseparated其他一些看起来不像split()函数的名称。

于 2017-08-01T20:45:51.590 回答
1

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

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

这将返回[9, 19, 24]

于 2017-08-01T20:55:14.590 回答
1

任意输入的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
于 2017-08-01T21:22:24.673 回答
1

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)

izip如果需要生成器,请在 Python 2 中使用(或使用 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)

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

于 2017-08-01T21:23:33.503 回答
1

一个使用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
于 2017-08-01T22:18:59.597 回答