60

現在、私はこのようなコードをいくつか持っています

import numpy as np
ret = np.array([])
for i in range(100000):
  tmp =  get_input(i)
  ret = np.append(ret, np.zeros(len(tmp)))
  ret = np.append(ret, np.ones(fixed_length))

ret をその場で変更するのではなく、配列のコピーを返す必要があるため、このコードは効率的ではないと思いますnp.append

extend次のようなnumpy配列に を使用できるかどうか疑問に思っていました:

import numpy as np
from somewhere import np_extend
ret = np.array([])
for i in range(100000):
  tmp =  get_input(i)
  np_extend(ret, np.zeros(len(tmp)))
  np_extend(ret, np.ones(fixed_length))

そのため、extendはるかに効率的になります。誰かがこれについてアイデアを持っていますか? ありがとう!

4

4 に答える 4

68

numpy 配列が 1 つの連続したメモリ ブロックを占有していると想像してください。ここで、numpy 配列の左右のメモリを占有している他のオブジェクト、たとえば他の numpy 配列を想像してみてください。numpy 配列に追加または拡張する余地はありません。numpy 配列内の基になるデータは、常に連続したメモリ ブロックを占有します。

したがって、numpy 配列に追加または拡張する要求は、まったく新しい大きなメモリ ブロックを割り当て、古いデータを新しいブロックにコピーしてから追加または拡張することによってのみ満たすことができます。

そう:

  1. インプレースでは発生しません。
  2. それは効率的ではありません。
于 2012-11-04T02:43:10.230 に答える
20

.resize()ndarraysのメソッドを使用できます。メモリが他の配列/変数によって参照されていないことが必要です。

import numpy as np
ret = np.array([])
for i in range(100):
    tmp = np.random.rand(np.random.randint(1, 100))
    ret.resize(len(ret) + len(tmp)) # <- ret is not referred to by anything else,
                                    #    so this works
    ret[-len(tmp):] = tmp

通常の配列メモリの過剰割り当てスキームを使用すると、効率を向上させることができます。

于 2012-11-04T03:01:30.313 に答える
16

これを処理する通常の方法は、次のようなものです。

import numpy as np
ret = []
for i in range(100000):
  tmp =  get_input(i)
  ret.append(np.zeros(len(tmp)))
  ret.append(np.zeros(fixed_length))
ret = np.concatenate(ret)

他の回答が得られた理由により、データをコピーせずに配列を拡張することは一般に不可能です。

于 2012-11-04T17:13:11.283 に答える