2017-04-07 73 views
0

我想創建一個非常大的數字向量,但該向量的長度未知。不過,我可以給出一個最大長度(大概是100k),儘管很可能這個列表實際上會在10k左右。基本上,我有一個for循環,在這個循環中我一直向矢量添加數字,直到滿足某個標準。將元素動態添加到未知最終長度的NumPy數組中

我在做這第一次嘗試用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

初始化'np.zeros /空「,最後切片。 – Divakar

+1

您對'np.append'的使用是錯誤的 - 遠離該函數。列表追加方法通常是最快的 - 即使最後的'np.array'調用需要時間。 http://stackoverflow.com/questions/43237035/append-a-numpy-array-to-a-certain-numpy-array-stored-in-a-list – hpaulj

+1

我同意Divakar。使用np.zeros(initial_size_guess)創建一個初始數組,並跟蹤您向矢量(n)添加了多少個數字,然後對矢量進行切片以僅獲取前n個元素。 – Alex

回答

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