6

状態空間を表す 2D numpy 配列 S があり、80000000 行 (状態として) と 5 列 (状態変数として) があります。

K0 を S で初期化し、各反復で状態遷移関数 f(x) を Ki のすべての状態に適用し、f(x) が Ki に含まれていない状態を削除して、結果として Ki+1 になります。収束するまで、つまり Ki+1 = Ki です。

このようにすると、何年もかかります:

K = S
to_delete = [0]
While to_delete:
    to_delete = []
    for i in xrange(len(K)):
        if not f(i) in K:
        to_delete.append(K(i))
    K = delete(K,to_delete,0)

だから私はベクトル化された実装を作りたかった:

K を列にスライスし、f を適用して、もう一度それらを結合すると、何らかの形で f(K) が得られます。

ここでの問題は、長さ len(K) の配列、たとえば Sel を取得する方法です。ここで、各行 Sel[i] は f(K[i]) が K にあるかどうかを決定します。関数 in1d とまったく同じように機能します。

それなら作るのは簡単だろう

K=K[Sel]]
4

3 に答える 3

0

上記の答えは素晴らしいです。

しかし、構造化された配列と混ざりたくない場合や、配列の型や配列要素の次元を気にしないソリューションが必要な場合は、次のように思いつきました。

k[np.in1d(list(map(np.ndarray.dumps, k)), list(map(np.ndarray.dumps, k2)))]

基本的に、list(map(np.ndarray.dumps, k))代わりにk.view(dtype='f8,f8').reshape(k.shape[0])

このソリューションは最大 50 倍遅いことを考慮してください。

k = np.array([[6.5, 6.5],
       [3.5, 7.5],
       [7.5, 5.5],
       [7.5, 3.5],
       [1.5, 3.5],
       [1.5, 5.5],
       [7.5, 6.5],
       [3.5, 8.5],
       [6.5, 1.5],
       [6.5, 0.5]])
k = np.tile(k, (1000, 1))

k2 = np.c_[k[:, 0] - 1, k[:, 1] + 1]


In [132]: k.shape, k2.shape
Out[132]: ((10000, 2), (10000, 2))

In [133]: timeit k[np.in1d(k.view(dtype='f8,f8').reshape(k.shape[0]),k2.view(dtype='f8,f8').reshape(k2.shape[0]))]
10 loops, best of 3: 22.2 ms per loop

In [134]: timeit k[np.in1d(list(map(np.ndarray.dumps, k)), list(map(np.ndarray.dumps, k2)))]
1 loop, best of 3: 892 ms per loop

小さな入力の場合はわずかですが、op の場合は 2 分ではなく 1 時間 20 分かかります。

于 2016-07-27T20:25:56.470 に答える