2017-04-07 6 views
0

非常に大きなベクトルを作成したいが、そのベクトルの長さはわからない。しかし、リストは実際には約10kになるでしょうが、最大長(約100k)にすることができます。本質的に、私はforループを持っています。その中で、特定の基準が満たされるまで、ベクトルに数値を追加し続けます。これを行うに未知の最終的な長さのNumPy配列に要素を動的に追加する

私の最初の試みは、私は次のように使用するPythonのリスト、としたが、最終的に私は、さらなる処理のために、numpyのアレイに、このリストを変換したい

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

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

初期化/空になり、最後にスライスします。 – Divakar

+1

あなたの 'np.append'の使用は間違っています - その機能から離れてください。最後の 'np.array'呼び出しに時間がかかっても、リストの追加アプローチは通常最速です。 http://stackoverflow.com/questions/43237035/append-a-numpy-array-to-a-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 

`np.zerosを持つ配列連結アプローチ

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 
関連する問題