在数组或列表中找到最密集区域的最快方法是什么?

时间:2018-11-17 19:07:29

标签: python statistics

我有一百万个元素的数组:0或1:

 example = np.array([0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,0,0,1,0,...]

我需要找到阵列中最密集的1区域。继续上面的示例,输出可能是密集区域开始的索引:3对应于:...1,1,1,1,1,1,1,0,1,1,1,1,...,其命中率为11/12或{{1} }。

当然,如果我指定窗口长度(提前),确定最密集的区域可能是最容易的,但是理想情况下,我不必这样做:它只会找到一个人的百分比的最高比率到区域的长度,但是我还需要它快速计算,因此我假设无论如何都必须指定窗口长度。

我可以天真地使用循环,甚至更糟的是嵌套循环,但这对于数百万个数字来说太慢了。因此,我想知道是否有一些Numpy魔术本质上可以识别密集区域或最高总和区域或类似的东西。

有人知道具有此功能的软件包吗?脾气暴躁? scipy.stats?如果我将其转换为矩阵,是否有办法同时或固定地到达每个区域?感谢您的建议!

编辑:

接受固定的窗口大小限制!假设窗口是数组总长度的91.67%,我将如何查找数字最大的1%区域(例如,从1%1.5%)在所有可能的区域(数组长度-1)中。

2 个答案:

答案 0 :(得分:2)

您可以使用卷积检查具有特定大小的区域的密度。这将为您提供输入窗口大小的最密集区域的第一个实例的开始位置。

import numpy as np
def densest(array, size):
    density = np.convolve(array, np.ones([size]), mode='valid')
    return np.argmax(density)

example = np.array([0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,0,0,1,0])

print( densest(example, 10) )
# 3

答案 1 :(得分:2)

其他更为冗长且可能是最慢的选项:

import numpy as np

ary = np.array([0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,0,0,1,0,1,0])

result = []
ones = {'idx': 0, 'count': 0}
for idx, x in np.ndenumerate(ary):
  if x == 1:
    ones['count'] += 1
    ones['idx'] = idx[0]
  if x == 0 and ones['count'] > 0:
    ones['idx'] = ones['idx'] - ones['count'] + 1
    result.append(ones)
    ones = {'idx': 0, 'count': 0}

它返回一个字典,其中所有区域都带有一个,索引开始和计数:

print(result)
#=> [{'idx': 3, 'count': 7}, {'idx': 11, 'count': 4}, {'idx': 18, 'count': 1}, {'idx': 21, 'count': 2}, {'idx': 24, 'count': 1}, {'idx': 30, 'count': 1}, {'idx': 32, 'count': 1}]

然后您可以选择最大值:

print (max(result, key=lambda x: x['count']))
#=> {'idx': 3, 'count': 7}