給定一個 nxm 整數矩陣 (n > m),我想識別是單個其他行的倍數的行,因此不是多個其他行的線性組合。我可以將所有行縮放到它們的長度并找到唯一的行,但這很容易出現浮點數的數字問題,并且也不會檢測到彼此相反(指向另一個方向)的向量。有任何想法嗎?
例子
A = array([[-1, -1, 0, 0],
[-1, -1, 0, 1],
[-1, 0, -1, 0],
[-1, 0, 0, 0],
[-1, 0, 0, 1],
[-1, 0, 1, 1],
[-1, 1, -1, 0],
[-1, 1, 0, 0],
[-1, 1, 1, 0],
[ 0, -1, 0, 0],
[ 0, -1, 0, 1],
[ 0, -1, 1, 0],
[ 0, -1, 1, 1],
[ 0, 0, -1, 0],
[ 0, 0, 0, 1],
[ 0, 0, 1, 0],
[ 0, 1, -1, 0],
[ 0, 1, 0, 0],
[ 0, 1, 0, 1],
[ 0, 1, 1, 0],
[ 0, 1, 1, 1],
[ 1, -1, 0, 0],
[ 1, -1, 1, 0],
[ 1, 0, 0, 0],
[ 1, 0, 0, 1],
[ 1, 0, 1, 0],
[ 1, 0, 1, 1],
[ 1, 1, 0, 0],
[ 1, 1, 0, 1],
[ 1, 1, 1, 0]])
例如,第 0 行和 -3 行只是指向相反的方向(乘以 -1 使它們相等)。
uj5u.com熱心網友回復:
您可以將每一行除以它的 GCD 進行歸一化:
import numpy as np
def normalize(a):
return a // np.gcd.reduce(a, axis=1, keepdims=True)
您可以定義一個將相反向量視為相等的距離:
def distance(a, b):
equal = np.all(a == b) or np.all(a == -b)
return 0 if equal else 1
然后你可以使用標準的聚類方法:
from scipy.spatial.distance import pdist
from scipy.cluster.hierarchy import linkage, fcluster
def cluster(a):
norm_a = normalize(a)
distances = pdist(norm_a, metric=distance)
return fcluster(linkage(distances), t=0.5)
例如:
>>> A = np.array([( 1, 2, 3, 4),
... ( 0, 2, 4, 8),
... (-1, -2, -3, -4),
... ( 0, 1, 2, 4),
... (-1, 2, -3, 4),
... ( 2, -4, 6, -8)])
>>> cluster(A)
array([2, 3, 2, 3, 1, 1], dtype=int32)
解釋:第4行和第5行構成簇1,第0行和第2行構成簇2,第1行和第3行構成簇3。
uj5u.com熱心網友回復:
您可以利用兩個歸一化線性相關向量的內積給出 1 或 -1 的事實,因此代碼可能如下所示:
>>> A_normalized = (A.T/np.linalg.norm(A, axis=-1)).T
>>> M = np.absolute(np.einsum('ix,jx->ij', A_normalized, A_normalized))
>>> i, j = np.where(np.isclose(M, 1))
>>> i, j = i[i < j], j[i < j] # Remove repetitions
>>> print(i, j)
輸出: [ 0 2 3 6 7 9 11 13] [27 25 23 22 21 17 16 15]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/361994.html
上一篇:在二維陣列中找到一個塊的中心
