动态添加元素到未知最终长度为

时间:2017-04-07 17:23:14

标签: python numpy

我想创建一个非常大的数字向量,但该向量的长度是未知的。但是,我可以给出一个最大长度(大约是100k),尽管列表实际上大概是10k左右。基本上,我有一个for循环,在其中我不断向向量添加数字,直到满足某个标准。

我的第一次尝试是使用Python列表,我在其中使用了以下内容:

x = []
for i in range(K):
    y = get_list_of_numbers()
    x += y

但是,最终我想将此列表转换为NumPy数组,以便进一步处理。如果我使用a = np.array(x)执行此操作,则创建该数组需要很长时间。

所以,我的第二个解决方案是从头开始创建一个空的NumPy数组,并在我进行时添加元素:

x = np.empty([])
for i in range(K):
    y = get_list_of_numbers()
    np.append(x, y)

但是,np.append(x, y)需要很长时间才能处理。

所以,我的解决方案都很慢。那里有更快的解决方案吗?

我能想到的唯一剩下的解决方案是以最大长度创建一个巨大的NumPy数组,然后将每个元素插入该数组中的相应插槽中。然而,这将是非常低效的内存,因为我没有真正估计最大向量长度......

谢谢!

1 个答案:

答案 0 :(得分:0)

如果我定义:

def get_list_of_numbers():
    n = np.random.randint(0,10)
    return list(range(n))

def foo(K):
    x=[]
    for i in range(K):
        y = get_list_of_numbers()
        x.extend(y)
    return x

简单地调用get_list_of_numbers需要花费最多的时间。将结果转换为数组并不需要花费太多时间:

In [69]: timeit foo(1000)
100 loops, best of 3: 5.9 ms per loop
In [70]: timeit np.array(foo(1000))
100 loops, best of 3: 6.38 ms per loop
In [73]: timeit -n1000 get_list_of_numbers()
1000 loops, best of 3: 6.04 µs per loop

让我们尝试预分配方法:

def foo1(K):
    x = np.zeros(K*10,int)
    cnt = 0
    for i in range(K):
        y = get_list_of_numbers()
        n = len(y)
        x[cnt:cnt+n] = y
        cnt += n
    x = x[:cnt]
    return x

In [80]: timeit foo1(1000)
100 loops, best of 3: 10.1 ms per loop

数组连接方法

In [48]: def foo1(K):
    ...:     x = np.zeros(0,int)
    ...:     for i in range(K):
    ...:         y = get_list_of_numbers()
    ...:         x = np.concatenate((x, y), axis=0)
    ...:     return x
In [51]: timeit foo1(1000).shape
100 loops, best of 3: 15.9 ms per loop