Несколько диапазонов / np.arange

У меня есть два массива конечных точек, которые выглядят так:

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)])

Это решение медленное, и я уверен, что его все еще можно значительно улучшить, полностью заменив комбинацию zip и понимания списка некоторыми функциями полностью в Numpy, просто я не знаю, как это сделать. Можете ли вы, ребята, показать мне самый эффективный способ сделать это?

Спасибо, ребята, заранее


Код для создания этих двух массивов:

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

Вы также можете попробовать опубликовать сообщение в проверка кода, чтобы получить отзывы об оптимизации.

flurble 30.04.2019 10:47

@cricate никогда не знал, что существует код-ревью. Я думаю, мне действительно нужно изучить это

mathguy 30.04.2019 10:49

Возможный дубликат Numpy версия этого конкретного понимания списка. На исходный вопрос, хотя и плохо сформулированный, есть ответ. Этот вопрос должен был быть обновлен с заданным здесь вопросом, а не задаваться заново.

9769953 30.04.2019 10:57

Это больше не дубликат вопроса, потому что здесь я специально прошу полную реализацию решения NumPy, чтобы обойти медленное понимание списка.

mathguy 30.04.2019 11:01

@cripcate, вы действительно смотрели на пустые вопросы на code review? Подобные вопросы являются обычными для SO.

hpaulj 30.04.2019 16:49

@hpaulj нет, я этого не делал. Я просто пошел с SO-решением, упомянув недостатки OP, когда не смог или был слишком ленив, чтобы сформулировать адекватный ответ: D

flurble 30.04.2019 16:54
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
7
6
1 634
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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'
)

Другие вопросы по теме