2016-07-31 10 views
2

NumPyを使用してデータを行列に格納しています。 以下のPythonコードのパフォーマンスが向上するように苦労しています。 RESULTはデータを格納したいデータストアです。NumPyで各行と列に沿って独自の関数を適用する方法

TMP = np.array([[1,1,0],[0,0,1],[1,0,0],[0,1,1]]) 
n_row, n_col = TMP.shape[0], TMP.shape[0] 
RESULT = np.zeros((n_row, n_col)) 

def do_something(array1, array2): 
    intersect_num = np.bitwise_and(array1, array2).sum() 
    union_num = np.bitwise_or(array1, array2).sum() 
    try: 
     return intersect_num/float(union_num) 
    except ZeroDivisionError: 
     return 0 

for i in range(n_row): 
    for j in range(n_col): 
    if i >= j: 
     continue 
    RESULT[i, j] = do_something(TMP[i], TMP[j]) 

私は、forループの代わりに、いくつかのnumpyの組み込み関数を使用することができれば、それははるかに高速になると思います。

私はここでさまざまな質問をしていましたが、自分の問題に最も適したものを見つけることができませんでした。 提案がありますか?前もって感謝します!あなたはベクトル化ソリューションとして、このような何かを行うことができ

+0

一般的なソリューションをお探しの場合は、リンクされた質問を使用してください。特定の機能については、質問を編集してください。 – Divakar

+0

'duplicate'はおそらくその年齢と高得点のために選ばれました。それが示唆するのは 'np.vectorize'です。上の三角形をスキップしているという事実は無視されます。範囲内のjに対して(I、ncol) 'を試してください。 Betterについては、機能の詳細を教えてください。 – hpaulj

+0

'np.vectorize'は、ヘルプ放送が必要な場合に便利です。そうでなければ構文的砂糖です。この場合、有害な可能性があります。まず、テスト計算で戻り値の型を評価しようとします。また、インデックスではなく値を提供します。したがって、上三角または下三角をテストする方法はありません – hpaulj

答えて

1

アプローチ#1

- TMP1s0sを保持していると例については

# Store number of rows in TMP as a paramter 
N = TMP.shape[0] 

# Get the indices that would be used as row indices to select rows off TMP and 
# also as row,column indices for setting output array. These basically correspond 
# to the iterators involved in the loopy implementation 
R,C = np.triu_indices(N,1)  

# Calculate intersect_num, union_num and division results across all iterations 
I = np.bitwise_and(TMP[R],TMP[C]).sum(-1) 
U = np.bitwise_or(TMP[R],TMP[C]).sum(-1) 
vals = np.true_divide(I,U) 

# Setup output array and assign vals into it 
out = np.zeros((N, N)) 
out[R,C] = vals 

アプローチ#2

、それらnp.bitwise_andnp.bitwise_orは交換可能ですより速い選択肢になる可能性があります。したがって、これらの実装では、このような実装が可能です。

M = TMP.shape[1] 
I = TMP.dot(TMP.T) 
TMP_inv = 1-TMP 
U = M - TMP_inv.dot(TMP_inv.T) 
out = np.triu(np.true_divide(I,U),1) 
+0

まさにそうです。私はコードを編集しました。ありがとう – yukimilk

+0

@yukimilkまた、 'TMP'は常に' 1s'と '0s'しか持っていませんか? – Divakar

+0

はい。 np.intのタイプとして0または1しかありません – yukimilk

関連する問題