我想在一個二維陣列(夫婦)中分組以查看家庭:
rij = [[11, 2], [15, 6], [7, 8], [3, 6], [9, 2], [2, 3], [2, 3]]
rij = np.sort(rij, axis=1) #sort inside array
rij = np.unique(rij, axis=0) #remove duplicates
在這段代碼之后,我得到了這個:
[[ 2 3]
[ 2 9]
[ 2 11]
[ 3 6]
[ 6 15]
[ 7 8]
[ 7 20]]
這是我卡住的地方,我需要回圈查看該號碼是否已經存在。
預期結果(家庭)將是:
[2, 3, 6, 9, 11, 15]
[7, 8, 20]
很高興我可以在第二學位中添加學位,家庭。
[2, 3, 9, 11]
[6, 15]
[7, 8, 20]
家庭在 3 級。
[2, 3, 6, 9, 11, 15]
[7, 8, 20]
最后一個學位的家庭。(與本示例中的前一個相同)
[2, 3, 6, 9, 11, 15]
[7, 8, 20]
uj5u.com熱心網友回復:
我們可以使用 scipy 的稀疏矩陣和圖形模塊來解決這個問題。你rij形成一個鄰接矩陣。這是一個矩陣,如果兩個節點相連,則為 1,否則為 0。由此,我們可以計算其他屬性。
讓我們將此應用于您的問題。我們首先清理您的輸入。正如@Ali_Sh 指出的那樣,您的示例中存在不一致之處。第一個串列的rij元素與下面的排序和唯一陣列不同。我忽略第一行并從排序的唯一版本開始。
import numpy as np
pairings = ((2, 3), (2, 9), (2, 11), (3, 6), (6, 15), (7, 8), (7, 20))
pairings = np.array(pairings)
ID 不連續。這將進一步浪費資源,所以讓我們壓縮我們的范圍。索引將是圖節點。索引處的值是 中的原始 ID pairings。我們可以將其用作查找表。對于逆映射,我使用了一個簡單的字典。
node_to_id = np.unique(np.sort(np.ravel(pairings)))
id_to_node = {id_: node for node, id_ in enumerate(node_to_id)}
現在我們構建一個稀疏鄰接矩陣。如果 matrix[i, j] 為真,則節點 i 連接到節點 j。由于我們的“家庭”關系是無向的(如果 i 與 j 相關,則 j 始終與 i 相關),因此我們構建了一個對稱矩陣。
Scipy 聲稱具有對稱矩陣的有向圖演算法速度更快。所以這使我們能夠做到這一點。
圖演算法需要CSR格式(壓縮稀疏行)。我們從 DOK 格式(鍵字典)開始,然后進行轉換,因為它更容易構建。由于我們的輸入已排序,LIL 格式(串列串列)可能更快,但如果我們不事先排序,DOK 具有更好的最壞情況性能。
from scipy import sparse
n_nodes = len(node_to_id)
dok_mat = sparse.dok_matrix((n_nodes, n_nodes), dtype=bool)
for left, right in pairings:
row, col = id_to_node[left], id_to_node[right]
dok_mat[row, col] = True
dok_mat[col, row] = True # undirected graph
csr_mat = dok_mat.tocsr()
del dok_mat
互聯組件給了我們我們的家人。對于矩陣中的每一行,我們都會得到一個標記其組件的整數標簽。
import collections
from scipy.sparse import csgraph
_, components = csgraph.connected_components(csr_mat)
families = collections.defaultdict(list)
for id_, component in zip(node_to_id, components):
families[component].append(id_)
print("families", list(families.values()))
最短路徑給出跳數,即相關距離。不相關的節點有無限的距離。
shortest_paths = csgraph.shortest_path(csr_mat)
maxdist = 2.
for id_, row in zip(node_to_id, shortest_paths):
immediate_family = node_to_id[row <= maxdist]
print(id_, immediate_family)
輸出將是
families [[2, 3, 6, 9, 11, 15], [7, 8, 20]]
2 [ 2 3 6 9 11]
3 [ 2 3 6 9 11 15]
6 [ 2 3 6 15]
7 [ 7 8 20]
8 [ 7 8 20]
9 [ 2 3 9 11]
11 [ 2 3 9 11]
15 [ 3 6 15]
20 [ 7 8 20]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/361998.html
