2

マトリックス a の k 個の最大値の位置 (インデックス) がバイナリ インジケーター マトリックス b と同じ位置にあるかどうかを判断する必要があります。

import numpy as np
a = np.matrix([[.8,.2,.6,.4],[.9,.3,.8,.6],[.2,.6,.8,.4],[.3,.3,.1,.8]])
b = np.matrix([[1,0,0,1],[1,0,1,1],[1,1,1,0],[1,0,0,1]])
print "a:\n", a
print "b:\n", b

d = argsort(a)
d[:,2:] # Return whether these indices are in 'b'

戻り値:

a:
[[ 0.8  0.2  0.6  0.4]
 [ 0.9  0.3  0.8  0.6]
 [ 0.2  0.6  0.8  0.4]
 [ 0.3  0.3  0.1  0.8]]
b:
[[1 0 0 1]
 [1 0 1 1]
 [1 1 1 0]
 [1 0 0 1]]

matrix([[2, 0],
        [2, 0],
        [1, 2],
        [1, 3]])

b最後の結果から返されたインデックスを比較し、それらの位置にある場合はカウントを返したいと思います。この例では、最終的に望ましい結果は次のようになります。

1
2
2
1

つまり、 の最初の行でaは、上位 2 つの値が の値の 1 つだけに対応しますb

これを効率的に行う方法はありますか?たぶん、ここでは argsort が間違ったアプローチです。ありがとう。

4

3 に答える 3

1

argsort取得すると、最小値0から最大値まで取得されるため、最大値と最小値を取得するために3逆にすることができます。[::-1]03

s = np.argsort(a, axis=1)[:,::-1]   
#array([[0, 2, 3, 1],
#       [0, 2, 3, 1],
#       [2, 1, 3, 0],
#       [3, 1, 0, 2]])

これで、最大値の s と 2 番目の最大値の snp.takeを取得するために使用できます。01

s2 = s + (np.arange(s.shape[0])*s.shape[1])[:,None]
s = np.take(s.flatten(),s2)
#array([[0, 3, 1, 2],
#       [0, 3, 1, 2],
#       [3, 1, 0, 2],
#       [2, 1, 3, 0]])

ではb、次のように0値を に置き換える必要があります。np.nan0==np.nanFalse

b = np.float_(b)
b[b==0] = np.nan
#array([[  1.,  nan,  nan,   1.],
#       [  1.,  nan,   1.,   1.],
#       [  1.,   1.,   1.,  nan],
#       [  1.,  nan,  nan,   1.]])

次の比較により、望ましい結果が得られます。

print np.logical_or(s==b-1, s==b).sum(axis=1)
#[[1]
# [2]
# [2]
# [1]]

nの最大値をaバイナリと比較する一般的なケースb:

def check_a_b(a,b,n=2):
    b = np.float_(b)
    b[b==0] = np.nan
    s = np.argsort(a, axis=1)[:,::-1]
    s2 = s + (np.arange(s.shape[0])*s.shape[1])[:,None]
    s = np.take(s.flatten(),s2)
    ans = s==(b-1)
    for i in range(n-1):
        ans = np.logical_or( ans, s==b+i )
    return ans.sum(axis=1)

これにより、 でペアごとの比較が行われますlogical_or

于 2013-08-08T09:19:34.997 に答える
1

次の事実に基づいた、よりシンプルではるかに高速な別のアプローチ:

True*1=1, True*0=0, False*0=0, and False*1=0

は:

def check_a_b_new(a,b,n=2):
    s = np.argsort(a.view(np.ndarray), axis=1)[:,::-1]
    s2 = s + (np.arange(s.shape[0])*s.shape[1])[:,None]
    s = np.take(s.flatten(),s2)
    return ((s < n)*b.view(np.ndarray)).sum(axis=1)

0へのnp.nan変換と、 のfor値が大きいと動作がかなり遅くなる Python ループを回避しますn

于 2013-08-08T15:29:43.490 に答える