次の2列配列では、最初の列の "edges"に対応する2番目の列から項目を選択します。現実の私のa
には、何百万行もの可能性があるため、これは単なる例です。だから、理想的には、これをできるだけ早く行い、中間結果を作成しないでください。中間インデックス配列を持たないnumpy配列から高速選択する方法
import numpy as np
a = np.array([[1,4],[1,2],[1,3],[2,6],[2,1],[2,8],[2,3],[2,1],
[3,6],[3,7],[5,4],[5,9],[5,1],[5,3],[5,2],[8,2],
[8,6],[8,8]])
すなわち私はここa[:,0]
変化に対応しa[:,1]
のエントリである
desired = np.array([4,6,6,4,2])
、結果を検索します。
一つの解決策は、np.array([6,6,4,2])
を与える
b = a[(a[1:,0]-a[:-1,0]).nonzero()[0]+1, 1]
ですが、私は単純に、何の問題を最初の項目を付加することができませんでした。ただし、これにより、最初の項目のインデックスの中間配列が作成されます。私は、リストの内包表記を使用することにより中間体を避けることができます:
c = [a[i+1,1] for i,(x,y) in enumerate(zip(a[1:,0],a[:-1,0])) if x!=y]
これも[6,6,4,2]
を与えます。生成元ベースのzip
(Python 3ではtrue)を仮定すると、これは中間表現を作成する必要はなく、非常にメモリ効率が良いはずです。しかし、内側のループはnumpyではなく、リストを生成する必要があります。リストをnumpyの配列に戻す必要があります。
メモリ効率がc
で、速度効率がb
のnumpy専用のバージョンがありますか?理想的には、a
以上のパスが1回だけ必要です。
a
が非常に大きい場合を除いて、スピードを測定してもそれほど役に立ちませんので、私はベンチマークを行うことを迷うことはありません。理論的に高速でメモリ効率の良いものがほしいと思っています。 。a
の行をファイルからストリーミングとアクセスに遅いですしていると仮定 - b
ソリューションを避けるために別の理由、それはa
上の第二ランダムアクセスパスを必要とする)
編集:大a
を生成する方法試験用マトリックス:
from itertools import repeat
N, M = 100000, 100
a = np.array(zip([x for y in zip(*repeat(np.arange(N),M)) for x in y ], np.random.random(N*M)))
もっと一般的な質問は、単純に「numpy配列よりもストリーミング(ジェネレータのような)操作を実行するにはどうすればよいですか? – Steve
* "...できるだけ早く、中間結果を作成しないで..." *これらは時には矛盾する目標です。より重要なのは、最高のパフォーマンスまたは最小限のメモリ使用ですか? –
まあ、 "メモリを浪費しない"ことではなく、まったくメモリに収まらないかもしれない配列のサイズで動作することができ、速度をあまり犠牲にしません。 (例えば、メモリマップされたファイルの配列)numpy.fromiterへの変換は、速度の10倍の犠牲を意味すると思われることは残念です。 – Steve