我需要檢查包含整數值的矩陣中是否有任何相同的行例如:
A = [[ 2 0 0 0 0 0 0]
[ 2 3 5 0 0 0 0]
[ 2 3 0 0 0 0 0]
[ 2 0 5 7 0 0 0]
[ 2 0 5 0 8 0 10]
[ 2 3 5 0 0 9 0]
[ 0 0 0 7 8 9 0]
[ 0 0 5 7 8 9 0]
[ 0 0 0 7 8 9 0]
[ 0 0 5 0 0 0 10]]
這必須回傳: True
但在其他例子中:
B = [[ 2 0 0 0 0 0 0]
[ 2 3 5 0 0 0 0]
[ 2 3 0 0 0 0 0]
[ 2 0 5 7 0 0 0]
[ 2 0 5 0 8 0 10]
[ 2 3 5 0 0 9 0]
[ 0 0 1 7 8 9 0]
[ 0 0 5 7 8 9 0]
[ 0 0 0 7 8 9 0]
[ 0 0 5 0 0 0 10]]
這必須回傳: False
uj5u.com熱心網友回復:
方法一:使用 np.unique
您可以使用
np.uniqueover axis=0 來獲取唯一的行。在
return_counts=True回傳的時候每一行重復的數量。放置一個條件
c>1并檢查是否有任何行與該條件匹配.any()將為您提供您想要的。
def is_dup_simple(arr):
u, c = np.unique(arr, axis=0, return_counts=True)
return (c>1).any()
print(is_dup_simple(A))
print(is_dup_simple(B))
True
False
方法二:廣播
以下是您如何通過廣播操作來做到這一點。它的方式稍長一些,但讓您可以非常靈活地使用該方法(例如,在不同陣列之間查找重復項)
def is_dup(arr):
mask = ~np.eye(arr.shape[0], dtype=bool)
out = ((arr[None,:,:] == arr[:,None,:]).all(-1)&mask).any()
return out
print(is_dup(A))
print(is_dup(B))
True
False
分步廣播表——
arr[None,:,:] -> 1 , 10, 7 (adding new first axis)
arr[:,None,:] -> 10, 1 , 7 (adding new second axis)
--------------------------
== -> 10, 10, 7 (compare elements row-wise)
all(-1) -> 10, 10 (compare rows x rows)
& mask -> 10, 10 (diagonals false)
any() -> 1 (reduce to single bool)
--------------------------
解釋
從 10,7 陣列(10 行,7 列)中,您想要匹配元素,以便最終得到一個帶有布林值的 (10,10) 矩陣,該矩陣指示 7 行中的所有元素是否與任何元素匹配在任何其他行中。
mask = ~np.eye(arr.shape[0], dtype=bool)具體而言,它是一個 10,10 形狀的矩陣,沿對角線帶有假值。這樣做的原因是,因為您想忽略將行與其自身進行比較。稍后會詳細介紹這一點。從廣播的布爾運算開始 -
(arr[None,:,:] == arr[:,None,:])。這會產生一個 10,10,7 布爾陣列,它將每一行的元素與所有其他行進行比較(10 x 10 比較,匹配 7 個值)。現在,隨著
.all(-1)您減少最后一個軸并獲得一個包含 True 的 10,10 矩陣,如果所有 7 個元素都匹配任何其他行,否則即使單個元素不同,也為 false。接下來,正如您所意識到的,第 0 行將始終匹配第 0 行,因此第 1 行也將匹配第 1 行。因此,此矩陣中的對角線將始終為真。為了推斷是否有重復的行,我們必須忽略對角線的 True 值。這可以通過
&在掩碼(上面討論過)和 10,10 布爾陣列之間進行(與)運算來完成。因此發生的唯一變化是對角線元素變為 False 而不是 True。最后,
.any()如果新的 10,10 矩陣中的單個元素為 True(這表明存在行 x 與行 y 完全匹配且行 x 不是),則可以使用which will be True 將陣列減少為單個布林值與第 y 行相同,感謝掩碼)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/396545.html
