【问题标题】:Number of elements of numpy arrays inside specific bins特定箱内 numpy 数组的元素数
【发布时间】:2018-10-26 00:17:31
【问题描述】:

我有一组排序(一维)长度不等的数组(比如M0M1M2)。我想找出每个数组有多少元素在特定的数字范围内(其中数字范围由另一个排序数组中的相邻元素指定,比如zbin )。我想知道实现这一目标的最快方法是什么。

在这里,我给出了一个我想做的任务的小例子(以及我目前为实现所需功能而遵循的方法):

""" Function to do search query """
def search(numrange, lst):
    arr = np.zeros(len(lst))        
    for i in range(len(lst)):
        probe = lst[i]
        count = 0
        for j in range(len(probe)):
            if (probe[j]>numrange[1]): break
            if (probe[j]>=numrange[0]) and (probe[j]<=numrange[1]): count = count + 1   

        arr[i] = count
    return arr


""" Some example of sorted one-dimensional arrays of unequal lengths """
M0 = np.array([5.1, 5.4, 6.4, 6.8, 7.9])
M1 = np.array([5.2, 5.7, 8.8, 8.9, 9.1, 9.2])
M2 = np.array([6.1, 6.2, 6.5, 7.2])

""" Implementation and output """
lst = [M0, M1, M2]
zbin = np.array([5.0, 5.5, 6.0, 6.5])
zarr = np.zeros( (len(zbin)-1, len(lst)) )
for i in range(len(zbin)-1):
    numrange = [zbin[i], zbin[i+1]]
    zarr[i,:] = search(numrange, lst)

print zarr

输出:

[[ 2.  1.  0.]
 [ 0.  1.  0.]
 [ 1.  0.  3.]] 

在这里,最终输出 zarr 为我提供了每个数组(M0M1M2)在每个 bin 中的元素数量,可能来自 zbinviz . [5.0, 5.5][5.5, 6.0][6.0, 6.5]。)例如考虑 bin [5.0, 5.5]。数组 M0 在该 bin 中有 2 个元素(5.15.4),M11 个元素(5.2)和 M2该 bin 中有 0 个元素。这给出了zarr 的第一行,即[2,1,0]。可以以类似的方式获取zarr 的其他行。

在我的实际任务中,我将处理比我在此示例中给出的长度大得多的zbin,以及更大和更多的数组,例如M0M1...@987654349 @。所有Ms 和数组zbin 将始终排序。我想知道我设计的功能 (search()) 和我遵循的方法是否是实现所需功能的最佳和 最快 方法。我将非常感谢任何帮助。

【问题讨论】:

  • 该列表中通常会有多少个数组?这些数组会一直排序吗?
  • @Divakar :大约有 1000 个这样的数组(M)。它们将始终被排序。

标签: python arrays numpy


【解决方案1】:

我们可以利用排序的性质,因此在这个任务中使用np.searchsorted,就像这样 -

out = np.empty((len(zbin)-1, len(lst)),dtype=int)
for i,l in enumerate(lst):
    left_idx = np.searchsorted(l, zbin[:-1], 'left')
    right_idx = np.searchsorted(l, zbin[1:], 'right')
    out[:,i] = right_idx - left_idx

【讨论】:

  • Divakar:这是实现所需任务的好方法。非常感谢。 :-D
  • @SpghttCd 我会鼓励 OP 进行评估,或者至少我希望他们这样做。
  • :-) 来吧,把 np.histogram 放在你的数组上的一个循环中是如此的简单,以至于你已经可以接受 Ethans 的回答了。好的,如果答案中能逐字列出代码,那就太好了,但是 - 好吧,看看我在它下面的第一条评论。他只是比我快,所以我不会在这里发布这个解决方案作为答案。
  • @SiddTheKid 感谢您的计时!
  • Divakar:您的回答总是非常棒。谢谢。 :-)
【解决方案2】:

我猜想简单地遍历每个数组并调用 numpy.histogram 的性能很难超越。我猜你还没有尝试过,或者你会提到它!

您当然可以利用排序的特性来提出更快的解决方案,但我会先比较一下时间。

【讨论】:

  • @SiddTheKid 试试for m in [M0, M1, M2]: print(np.histogram(m, zbin)[0]) 我会对输出与您的输出之间的差异特别感兴趣。即:您如何计算您的垃圾箱中的值?因为 np.histogram 的输出对我来说很清楚...[2 0 1] [1 1 0] [0 0 3]
  • @Ethan:我正在利用数组的排序特性M 的一个地方是:if (probe[j]&gt;numrange[1]): break
  • @SpghttCd:上述方法:for m in [M0, M1, M2]: print(np.histogram(m, zbin)) 给我的答案与我想要的略有不同。差异可能很小 (+/- 1),但它会显着影响一些我在这里没有提到的进一步调查。
  • @SiddTheKidd 啊,哈哈!然后 np.histogram 只是给你转置的结果。列中的内容可以在行中找到。
  • @SiddTheKidd 是的,你的任务正是 np.histogram 的工作。
猜你喜欢
  • 2023-02-22
  • 2012-06-15
  • 1970-01-01
  • 2019-11-15
  • 2017-08-06
  • 2021-07-17
  • 2019-02-09
  • 1970-01-01
  • 2021-11-02
相关资源
最近更新 更多