【问题标题】:Find all occurences of a specified match of two numbers in numpy array在numpy数组中查找两个数字的指定匹配项的所有出现
【发布时间】:2016-09-13 18:07:40
【问题描述】:

我需要实现的是获取所有索引的数组,其中在我的数据数组中填充零和一是从零到一的步骤。我需要非常快速的解决方案,因为我必须处理数以百万计的数百万长度的数组。它将在计算中心运行。比如……

data_array = np.array([1,1,0,1,1,1,0,0,0,1,1,1,0,1,1,0])
result = [3,9,13]

【问题讨论】:

  • 那么,发布的任何一个解决方案都适合您吗?

标签: python arrays performance numpy


【解决方案1】:

试试这个:

In [23]: np.where(np.diff(a)==1)[0] + 1
Out[23]: array([ 3,  9, 13], dtype=int64)

100M元素数组的时序:

In [46]: a = np.random.choice([0,1], 10**8)

In [47]: %timeit np.nonzero((a[1:] - a[:-1]) == 1)[0] + 1
1 loop, best of 3: 1.46 s per loop

In [48]: %timeit np.where(np.diff(a)==1)[0] + 1
1 loop, best of 3: 1.64 s per loop

【讨论】:

  • 哦,我知道 numpy 有一个 diff 函数——虽然我认为它是一个数组方法。我喜欢这种简洁。 +1
  • @PaulH,谢谢!我也喜欢(已经;)你的回答——因为我不知道np.nonzero() 函数,所以我今天从你的回答中学到了一些新东西
【解决方案2】:

程序如下:

  1. 计算数组的差异
  2. 找到 diff == 1 的索引
  3. 在结果中加 1 (b/c len(diff) = len(orig) - 1)

所以试试这个:

index = numpy.nonzero((data_array[1:] - data_array[:-1]) == 1)[0] + 1
index
# [3, 9, 13]

【讨论】:

  • 我认为你的解决方案应该更快,因为nonzero函数...
  • FWIW,我在我的机器上看不到 nonzerowhere 之间的任何区别(对于 10**6 随机位,两者都在 6.6 毫秒左右)
  • 您的解决方案约为。在 10**8 阵列上快 12%...我会发布时间...
【解决方案3】:

非常感谢大家。非零的解决方案对我来说可能更好,因为我需要知道从 0->1 和 1->0 的步骤,最后计算差异。所以这是我的解决方案。任何其他建议表示赞赏。)

i_in  = np.nonzero(  (data_array[1:] - data_array[:-1]) ==  1   )[0] +1
i_out = np.nonzero(  (data_array[1:] - data_array[:-1]) == -1   )[0] +1

i_return_in_time = (i_in - i_out[:i_in.size] ) 

【讨论】:

    【解决方案4】:

    由于它是一个由0s1s 填充的数组,因此您可以受益于仅比较而不是在单移版本之间执行算术运算,从而直接为我们提供布尔数组,可以将其提供给np.flatnonzero为我们获取索引和最终输出。

    因此,我们会有这样的实现 -

    np.flatnonzero(data_array[1:] > data_array[:-1])+1
    

    运行时测试-

    In [26]: a = np.random.choice([0,1], 10**8)
    
    In [27]: %timeit np.nonzero((a[1:] - a[:-1]) == 1)[0] + 1
    1 loop, best of 3: 1.91 s per loop
    
    In [28]: %timeit np.where(np.diff(a)==1)[0] + 1
    1 loop, best of 3: 1.91 s per loop
    
    In [29]: %timeit np.flatnonzero(a[1:] > a[:-1])+1
    1 loop, best of 3: 954 ms per loop
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-28
      • 2018-02-22
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      • 2022-12-15
      相关资源
      最近更新 更多