Вы обращаетесь к ячейкам в памяти очень неэффективным способом. Вот простой тест, чтобы понять, почему:
a = np.zeros([1200, 2000, 100])
a[1,:,:] = 1 # time: 97.3 µs
a[:,1,:] = 1 # time: 345 µs
a[:,:,1] = 1 # time: 16 ms
Шаблон доступа к значениям первых измерений не эффективен. Это потому, что ячейки последнего измерения хранятся в памяти непрерывно , в отличие от других. Доступ к памяти несмежным способом, как правило, намного медленнее (чем больше шаг, тем медленнее он).
Поэтому рассмотрите возможность замены порядка измерений следующим образом:
reps = 100
ret100 = np.zeros([reps, 2000, 1200])
for k in range(reps):
ret100[k,:,:] = 1
print(k)
Это более чем в 10 раз быстрее на моей машине. Ускорение будет еще больше на больших массивах (например, с повторениями, установленными на 1000).