【问题标题】:Multiple ranges / np.arange [duplicate]多个范围/ np.arange [重复]
【发布时间】:2019-09-18 21:06:01
【问题描述】:

我有两个如下所示的端点数组:

t1 = np.array([0,13,22,...,99994])
t2 = np.array([4,14,25,...,99998])

我正在寻找最有效的方法来生成如下所示的输出:

np.array([0,1,2,3,4,13,14,22,23,24,25,...,99994,99995,99996,99997,99998])

一种方法是:

np.array([i for a, b in zip(t1, t2) for i in range(a, b + 1)])

这个解决方案很慢,我确信它仍然可以通过完全在 Numpy 中用一些函数完全替换 zip 和列表理解组合来大大改进,只是我不知道如何。你们能告诉我最有效的方法吗?

提前谢谢大家


生成这两个数组的代码:

import numpy as np

m =10000
Z = np.arange(0,10*m,10)

t1 = np.random.randint(5, size =m ) + Z
t2 =np.random.randint(5,size = m) + 5 + Z

【问题讨论】:

  • 您可能还想尝试在code-review 发帖以获取有关优化的反馈
  • @cricate 从来不知道存在代码审查。我想我真的需要调查一下
  • Numpy version of this particular list comprehension 的可能重复项。最初的问题,虽然措辞很糟糕,但有一个答案。该问题应该已更新为此处提出的问题,而不是重新提出。
  • 这不再是问题的重复,因为在这里我特别要求解决方案的完整 NumPy 实现以绕过慢速列表理解。
  • @cripcate,你真的看过code review上的numpy问题吗?像这样的问题在 SO 上是例行公事。

标签: python performance numpy zip list-comprehension


【解决方案1】:

这是一种使用numba 的高效方法:

from numba import njit

@njit
def n_ranges_nb(t1, t2):
    a = np.arange(np.max(t2)+1)
    n = (t2 - t1).sum()
    out = np.zeros(n)
    l, l_old = 0, 0
    for i,j in zip(t1, t2):
        l += j-i
        out[l_old:l] = a[i:j]
        l_old = l
    return out

检查与上述相同的值:

t1 = np.array([0,13,22])
t2 = np.array([4,14,25])

n_ranges_nb(t1, t2+1)
# array([ 0.,  1.,  2.,  3.,  4., 13., 14., 22., 23., 24., 25.])

让我们检查时间:

d = 100
perfplot.show(
    setup=lambda n: np.cumsum(np.random.randint(0, 50, n)),

    kernels=[
        lambda x: np.array([i for a, b in zip(x,x+d) for i in range(a,b+1)]),
        lambda x: n_ranges_nb(x, x+d+1),
        lambda x: create_ranges(x, x+d+1) # (from the dupe)
    ],

    labels=['nested-list-comp', 'n_ranges_nb', 'create_ranges'],
    n_range=[2**k for k in range(0, 18)],
    xlabel='N'
)

【讨论】:

    猜你喜欢
    • 2017-09-24
    • 2023-03-17
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多