У меня есть два массива конечных точек, которые выглядят так:
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
@cricate никогда не знал, что существует код-ревью. Я думаю, мне действительно нужно изучить это
Возможный дубликат Numpy версия этого конкретного понимания списка. На исходный вопрос, хотя и плохо сформулированный, есть ответ. Этот вопрос должен был быть обновлен с заданным здесь вопросом, а не задаваться заново.
Это больше не дубликат вопроса, потому что здесь я специально прошу полную реализацию решения NumPy, чтобы обойти медленное понимание списка.
@cripcate, вы действительно смотрели на пустые вопросы на code review? Подобные вопросы являются обычными для SO.
@hpaulj нет, я этого не делал. Я просто пошел с SO-решением, упомянув недостатки OP, когда не смог или был слишком ленив, чтобы сформулировать адекватный ответ: D






Вот эффективный подход с использованием 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'
)
Вы также можете попробовать опубликовать сообщение в проверка кода, чтобы получить отзывы об оптимизации.