1

日付でキー設定され、numpy.arrayである属性を持つクラスで満たされた辞書があります。np.dstackを使用して、辞書内のすべての配列から1つの大きな配列を作成したいと思います。私の現在のコードは次のようなものです:

import numpy as np
#PARTS is my dictionary
#the .partposit is the attribute that is an array of shape (50000, 12)
ks = sorted(PARTS.keys())
p1 = PARTS[ks[0]].partposit
for k in ks[1:]:
    p1 = np.dstack((p1, PARTS[k].partposit))

私の結果は私が期待する通りです:

In [67]: p1.shape
Out[67]: (50000, 12, 163)

ただし、かなり遅いです。これを行うためのより効率的な方法はありますか?

4

2 に答える 2

3

あなたはこれを試すことができます:

>>> import numpy as np
>>> class A:
...     def __init__(self, values):
...         self.partposit = values
... 
>>> PARTS = dict((index, A(np.zeros((50000, 12)))) for index in xrange(163))
>>> p1 = np.dstack((PARTS[k].partposit for k in sorted(PARTS.keys())))
>>> p1.shape
(50000, 12, 163)
>>> 

私のマシンにスタックするのに数秒かかりました。

>>> import timeit
>>> timeit.Timer('p1 = np.dstack((PARTS[k].partposit for k in sorted(PARTS.keys())))', "from __main__ import np, PARTS").timeit(number = 1)
2.1245520114898682

numpy.dstack配列のシーケンスを取り込んでスタックするので、自分で連続的にスタックするのではなく、リストを指定するだけの方がはるかに高速です。

numpy.dstack(tup)

配列を深さ方向に(3番目の軸に沿って)スタックします。一連の配列を取得し、それらを3番目の軸に沿ってスタックして、単一の配列を作成します。

http://docs.scipy.org/doc/numpy/reference/generated/numpy.dstack.html

私はまた、あなたの方法がどれくらいの長さになるかについても興味がありました:

>>> import timeit
>>> setup = """
... import numpy as np
... #PARTS is my dictionary
... #the .partposit is the attribute that is an array of shape (50000, 12)
... 
... class A:
...     def __init__(self, values):
...         self.partposit = values
... 
... PARTS = dict((index, A(np.zeros((50000, 12)))) for index in xrange(163))
... ks = sorted(PARTS.keys())
... """
>>> stack = """
... p1 = PARTS[ks[0]].partposit
... for k in ks[1:]:
...     p1 = np.dstack((p1, PARTS[k].partposit))
... """
>>> timeit.Timer(stack, setup).timeit(number = 1)
67.69684886932373

痛い!

>>> numpy.__version__
'1.6.1'

$ python --version
Python 2.6.1

これがお役に立てば幸いです。

于 2012-07-08T22:37:10.033 に答える
0

この行は、不要なオーバーヘッドである新しいリスト(浅いコピー)を作成します。

for k in ks[1:]:

これを行うためのより効率的な方法は次のとおりです。

itks =iter(ks)
next(itks)
for k in itks:

さらに、次の方法で繰り返しのルックアップを排除できます。

entries = iter(sorted(((k, v.partposit) for k,v in PARTS.iteritems()), key=lambda(k,v):k))
p1 = next(entries)[1]
for k,v in entries: 
    p1 = np.dstack((p1, v))

これにより、dictでのコピーと繰り返しのルックアップの両方が排除されるため、処理が少し速くなります(一定時間ではありますが、無料ではありません)。

于 2012-07-08T22:41:03.327 に答える