如果至少有一个值相等,则合并2d数组的行

时间:2018-01-18 20:17:55

标签: python arrays numpy

我正在努力实现以下目标。考虑矩阵

[[ 9 10]
 [10  9]
 [11 17]
 [11 18]
 [12 13]
 [13 12]
 [17 11]
 [17 18]
 [18 11]
 [18 17]]

我想"合并"所有行,至少有一个相似的值。对于这个例子,我想得到

[[9,10]
[11, 17, 18]
[12, 13]]

我知道numpy适用于固定形状的数组。因此,我尝试使用这些值填充另一个nans数组。一个简单的方法是for循环,我循环遍历每一行,检查结果数组是否已经有一个值,如果是,则扩展,如果没有放入下一个空行。 我没有使用numpy,使用列表列表来放置组。

groups = []
for pair in matrix:
    pair = [pair[0], pair[1]]
    append_pair = True                
    for sublist in groups:
        if pair[0] in sublist or pair[1] in sublist:
            sublist.extend(x for x in pair if x not in sublist)
            append_pair = False
    if append_pair is True:
        groups.append(pair)

有没有更好的numpy方式呢?

2 个答案:

答案 0 :(得分:2)

这是一种优化的方法,但有点hacky:

In [14]: def find_intersection(m_list):
            for i,v in enumerate(m_list) : 
                for j,k in enumerate(m_list[i+1:],i+1):
                       if np.in1d(v, k).any():
                              m_list[i] = np.union1d(v, m_list.pop(j))
                              return find_intersection(m_list)
            return m_list
   ....:         

In [15]: find_intersection(a)
Out[15]: [array([ 9, 10]), array([11, 17, 18]), array([12, 13])]

答案 1 :(得分:1)

如果您将每个子列表视为连接两个节点的边缘,则这是一个连接组件查找问题。如果您安装了networkx,则还可以使用networkx软件包的connected_components功能来解决此问题。

import networkx as nx

G = nx.from_edgelist([[ 9, 10],
                     [10,  9],
                     [11, 17],
                     [11, 18],
                     [12, 13],
                     [13, 12],
                     [17, 11],
                     [17, 18],
                     [18, 11],
                     [18, 17]])
list(nx.connected_components(G))
[{9, 10}, {11, 17, 18}, {12, 13}]

这是一个numpy问题。所以... Scipy解决方案将使用scipy.sparse.csgraph.connected_components。但它的用法并没有得到很好的记录。我建议你在这里使用networkx