1

次のコードを最適化しようとしていますが、Cython で書き直す可能性があります。単純に次元が低いが比較的長い numpy 配列を取り、その列で 0 の値を調べ、それらを配列で -1 としてマークします。コードは次のとおりです。

import numpy as np

def get_data():
    data = np.array([[1,5,1]] * 5000 + [[1,0,5]] * 5000 + [[0,0,0]] * 5000)
    return data

def get_cols(K):
    cols = np.array([2] * K)
    return cols

def test_nonzero(data):
    K = len(data)
    result = np.array([1] * K)
    # Index into columns of data
    cols = get_cols(K)
    # Mark zero points with -1
    idx = np.nonzero(data[np.arange(K), cols] == 0)[0]
    result[idx] = -1

import time
t_start = time.time()
data = get_data()
for n in range(5000):
    test_nonzero(data)
t_end = time.time()
print (t_end - t_start)

dataがデータです。colsゼロ以外の値を探すためのデータの列の配列です (簡単にするために、すべて同じ列にしました)。目標は、numpy 配列 を計算することです。この配列はresult、対象の列がゼロでない各行に対して 1 の値を持ち、対応する対象の列がゼロである行に対して -1 の値を持ちます。

15,000 行 x 3 列のそれほど大きくない配列でこの関数を 5000 回実行すると、約 20 秒かかります。これを高速化する方法はありますか?ほとんどの作業は、ゼロ以外の要素を見つけ、インデックスを使用してそれらを取得することに費やされているようです (インデックスの呼び出しnonzeroとその後の使用)。Cython の実装でこれを高速化するにはどうすればよいでしょうか?

4

1 に答える 1

2
cols = np.array([2] * K)

それは本当に遅くなるでしょう。これは、非常に大きな python リストを作成し、それを numpy 配列に変換します。代わりに、次のようにします。

cols = np.ones(K, int)*2

そのほうがずっと速くなる

result = np.array([1] * K)

ここで、次のことを行う必要があります。

result = np.ones(K, int)

これにより、numpy 配列が直接生成されます。

idx = np.nonzero(data[np.arange(K), cols] == 0)[0]
result[idx] = -1

cols は配列ですが、2 を渡すことができます。さらに、ゼロ以外を使用すると、余分な手順が追加されます。

idx = data[np.arange(K), 2] == 0
result[idx] = -1

同じ効果があるはずです。

于 2013-04-16T04:13:35.800 に答える