Ваш подход:
In [18]: arr = np.array([])
In [19]: for i in range(1000):
...: arr = np.insert(arr, arr.shape[0],[1,2,3])
...:
In [20]: arr.shape
Out[20]: (3000,)
In [21]: %%timeit
...: arr = np.array([])
...: for i in range(1000):
...: arr = np.insert(arr, arr.shape[0],[1,2,3])
...:
31.9 ms ± 194 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Сравните это с concatenate
:
In [22]: %%timeit
...: arr = np.array([])
...: for i in range(1000):
...: arr = np.concatenate((arr, [1,2,3]))
...:
5.49 ms ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
и с расширением списка:
In [23]: %%timeit
...: alist = []
...: for i in range(1000):
...: alist.extend([1,2,3])
...: arr = np.array(alist)
384 µs ± 13.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Мы не рекомендуем использоватьconcatenate
(или np.append
), потому что он медленный и его трудно инициализировать.Список добавляется или расширяется быстрее.Использование insert
даже хуже, чем concatenate
.
concatenate
каждый раз создает новый массив.insert
делает то же самое, но поскольку он предназначен для размещения новых значений в любом месте оригинала, он намного сложнее и, следовательно, медленнее.Посмотрите на его код, если вы мне не верите.
lists
предназначены для роста;новые элементы добавляются посредством простой вставки объекта (указателя) в буфер, который имеет рост.То есть рост происходит на месте.
Вставка в полный массив также довольно хороша:
In [27]: %%timeit
...: arr = np.zeros((1000,3),int)
...: for i in range(1000):
...: arr[i,:] = [1,2,3]
...: arr = arr.ravel()
1.69 ms ± 9.47 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)