numpy.insert 的性能取决于数组大小 - 解决方法?

使用以下代码,我的印象是插入到 numpy 数组中取决于数组大小。


是否有针对此性能限制的任何基于 numpy 的解决方法(或也不是基于 numpy 的)?


if True:

    import numpy as np

    import datetime

    import timeit

myArray = np.empty((0, 2), dtype='object')

myString = "myArray = np.insert(myArray, myArray.shape[0], [[ds, runner]], axis=0)"

runner = 1

ds = datetime.datetime.utcfromtimestamp(runner)

% timeit myString

19.3 ns ± 0.715 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

for runner in range(30_000):

    ds = datetime.datetime.utcfromtimestamp(runner)

    myArray = np.insert(myArray, myArray.shape[0], [[ds, runner]], axis=0)

print("len(myArray):", len(myArray))

% timeit myString

len(myArray): 30000

38.1 ns ± 1.1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)


繁星coding
浏览 244回答 2
2回答

哆啦的时光机

这与numpy工作方式有关。对于每个插入操作,它都会获取整个数组并将其存储在一个新位置。我建议使用listappend 并将其转换为numpy数组。也许这个问题的重复

慕斯王

你的方法: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(or 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python