Обратите внимание, что np.where
может также принимать два array_like аргумента, из которых можно выбирать в зависимости от условия . Вот как вы можете использовать np.where
в вашем случае:
for n in range(0, 365):
start = 24 + n*48
end = 46 + n*48
independent[start:end,0:5] = (np.where(independent== 0.05,
np.random.choice([0.0, 0.05],
size=independent.shape),
independent)[start:end,0:5])
Это немного сложно, но вышесказанное можно векторизовать. Ключом является получение списка диапазонов, где мы хотим обновить independent
. Для этого мы можем использовать n_ranges
из связанного ответа, который можно использовать для получения плоского массива со всеми диапазонами из соответствующих start
и end
:
start = 24 + np.arange(0, 365)*48
end = 46 + np.arange(0, 365)*48
ranges = n_ranges(start, end)
independent[ranges,0:5] = (np.where(independent== 0.05,
np.random.choice([0.0, 0.05],
size=independent.shape),
independent)[ranges,0:5])
Проверяя время, мы видим, что при втором подходе мы получаем ускорение 260x
!
def vect_approach(a):
start = 24 + np.arange(0, 365)*48
end = 46 + np.arange(0, 365)*48
ranges = n_ranges(start, end)
a[ranges,0:5] = (np.where(a== 0.05,
np.random.choice([0.0, 0.05], size=a.shape ),
a)[ranges,0:5])
def loopy_approach(x):
for n in range(0, 365):
start = 24 + n*48
end = 46 + n*48
independent[start:end,0:5] = (np.where(independent== 0.05,
np.random.choice([0.0, 0.05],
size=independent.shape),
independent)[start:end,0:5])
independent = np.zeros([17520,5])
%timeit loopy_approach(independent)
# 475 ms ± 19.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vect_approach(independent)
# 1.87 ms ± 95.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)