arr
最終的な配列が5000x10より大きくなることは決してないことを知っていると仮定します。次に、最大サイズの配列を事前に割り当て、ループを通過するときにデータを入力し、ループarr.resize
を終了した後に検出されたサイズに縮小するために使用できます。
以下のテストは、配列の最終的なサイズに関係なく、中間のpythonリストを作成するよりもわずかに高速になることを示しています。
また、arr.resize
未使用のメモリの割り当てを解除するため、最終的な(中間ではないかもしれませんが)メモリフットプリントは、によって使用されるものよりも小さくなりpython_lists_to_array
ます。
これnumpy_all_the_way
はより速いショーです:
% python -mtimeit -s"import test" "test.numpy_all_the_way(100)"
100 loops, best of 3: 1.78 msec per loop
% python -mtimeit -s"import test" "test.numpy_all_the_way(1000)"
100 loops, best of 3: 18.1 msec per loop
% python -mtimeit -s"import test" "test.numpy_all_the_way(5000)"
10 loops, best of 3: 90.4 msec per loop
% python -mtimeit -s"import test" "test.python_lists_to_array(100)"
1000 loops, best of 3: 1.97 msec per loop
% python -mtimeit -s"import test" "test.python_lists_to_array(1000)"
10 loops, best of 3: 20.3 msec per loop
% python -mtimeit -s"import test" "test.python_lists_to_array(5000)"
10 loops, best of 3: 101 msec per loop
これはnumpy_all_the_way
、使用するメモリが少ないことを示しています。
% test.py
Initial memory usage: 19788
After python_lists_to_array: 20976
After numpy_all_the_way: 20348
test.py:
import numpy as np
import os
def memory_usage():
pid = os.getpid()
return next(line for line in open('/proc/%s/status' % pid).read().splitlines()
if line.startswith('VmSize')).split()[-2]
N, M = 5000, 10
def python_lists_to_array(k):
list_of_arrays = list(map(lambda x: x * np.ones(M), range(k)))
arr = np.array(list_of_arrays)
return arr
def numpy_all_the_way(k):
arr = np.empty((N, M))
for x in range(k):
arr[x] = x * np.ones(M)
arr.resize((k, M))
return arr
if __name__ == '__main__':
print('Initial memory usage: %s' % memory_usage())
arr = python_lists_to_array(5000)
print('After python_lists_to_array: %s' % memory_usage())
arr = numpy_all_the_way(5000)
print('After numpy_all_the_way: %s' % memory_usage())