我有一个2D numpy数组,其中每行包含2个整数。我想找到属于共享公共元素的行的所有元素组(也就是边缘列表数组中图的连接组件)。例如,对于数组:
[[ 0 4]
[ 0 7]
[ 1 2]
[ 1 13]
[ 2 1]
[ 2 9]
[ 3 14]
[ 3 16]
[ 4 0]
[ 4 5]
[ 5 4]
[ 5 6]
[ 6 5]
[ 6 7]
[ 7 0]
[ 7 6]]
将包含组
[[ 0 4 5 6 7]
[ 1 2 13 9]
[ 3 14 16]]
答案 0 :(得分:2)
如果可以使用库,请假设您的数组为slotTexture.texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
(请注意,您不能将组件作为numpy数组使用,因为它们可以是numpy中不存在的非矩形数组,因此将它们作为集合输出) :
a
如果您需要一个没有额外库的纯numpyic解决方案,请查看以下通用解决方案: https://stackoverflow.com/a/61764414/4975981
答案 1 :(得分:1)
我确信有更快的方法,并且我不学习图论,但是您可以从这里开始;
x = [[ 0, 4],
[ 0, 7],
[ 1, 2],
[ 1, 13],
[ 2, 1],
[ 2, 9],
[ 3, 14],
[ 3, 16],
[ 4, 0],
[ 4, 5],
[ 5, 4],
[ 5, 6],
[ 6, 5],
[ 6, 7],
[ 7, 0],
[ 7, 6]]
nodes = list(set([item for sublist in x for item in sublist]))
grps = {n: g for n, g in zip(nodes, range(len(nodes)))}
for v in x:
t = grps[v[0]]
f = grps[v[1]]
if t != f:
for n in grps:
if grps[n] == f:
grps[n] = t
ret = [[k for k, v in grps.items() if v==g] for g in set(grps.values())]
print(ret)
答案 2 :(得分:1)
根据图论,您需要从一组边线创建一个图,然后找到该图的连接组件。基于纯df.join(df.groupBy('date', 'hos').pivot('time').agg(first('topwait').alias('topwait')), ['date', 'hos'], 'left') \
.show()
+---------+---+-----+-------+-----+-----+
| date|hos| time|topwait|11:00|12:00|
+---------+---+-----+-------+-----+-----+
|19/9/2020|KHW|11:00| 5| 5| 1|
|19/9/2020|CCM|11:00| 6| 6| 2|
|19/9/2020|HHJ|11:00| 7| 7| 4|
|19/9/2020|KHW|12:00| 1| 5| 1|
|19/9/2020|CCM|12:00| 2| 6| 2|
|19/9/2020|HHJ|12:00| 4| 7| 4|
|22/9/2020|KHW|11:00| 9| 9| 4|
|22/9/2020|CCM|11:00| 9| 9| 3|
|22/9/2020|HHJ|11:00| 9| 9| 2|
|22/9/2020|KHW|12:00| 4| 9| 4|
|22/9/2020|CCM|12:00| 3| 9| 3|
|22/9/2020|HHJ|12:00| 2| 9| 2|
+---------+---+-----+-------+-----+-----+
的解决方案对我来说似乎太难了,但是您仍然可以使用用C编写的numpy
使其达到C级(与纯Python的igraph
不同)。您需要先安装networkx
。
python-igraph
方法返回igraph.Graph.clusters()
类的特殊实例,可以将其转换为igraph.clustering.VertexClustering
:
list
import igraph
arr = np.array([[0, 4], [0, 7], [1, 2], [1, 9], [2, 1], [2, 8], [3, 10],
[3, 11], [4, 0], [4, 5], [5, 4], [5, 6], [6, 5], [6, 7], [7, 0], [7, 6]])
g = ig.Graph()
g.add_vertices(12)
g.add_edges(arr)
i = g.clusters()
print(list(i))
#output: [[0, 4, 5, 6, 7], [1, 2, 8, 9], [3, 10, 11]]
还支持绘制这些连接的组件,就像在igraph
中所做的那样,但是您可能需要从非官方二进制文件下载networkx
并安装它才能解锁pycairo
选项:
igraph.plot
请注意,如果使用初始数组而不是普通数组,则pal = ig.drawing.colors.ClusterColoringPalette(len(i)) #passing a number of colors
color = pal.get_many(i.membership) # a list of color codes for each vertex
ig.plot(g, bbox = (200, 100), vertex_label=g.vs.indices,
vertex_color = color, vertex_size = 12, vertex_label_size = 8)
会抛出igraph
。那是因为应该在添加边之前声明每个顶点,并且不允许所有顶点都有缺失的数字(事实上,这是允许的,但是重新索引是静默完成的,并且可以使用'name'属性访问旧名称)。可以通过编写自定义函数从重新标记的边创建图形来解决此问题:
InternalError
在输出中使用了新标签(因此使它不正确),但是仍然可以像这样访问旧标签:
def create_from_edges(edgelist):
g = ig.Graph()
u, inv = np.unique(edgelist, return_inverse=True)
e = inv.reshape(edgelist.shape)
g.add_vertices(u) #add vertices, not reindexed
g.add_edges(e) #add edges, reindexed
return g
arr = np.array([[0, 4], [0, 7], [1, 2], [1, 13], [2, 1], [2, 9], [3, 14],
[3, 16], [4, 0], [4, 5], [5, 4], [5, 6], [6, 5], [6, 7], [7, 0], [7, 6]])
g = create_from_edges(arr)
i = g.clusters()
print(list(i))
#output: [[0, 4, 5, 6, 7], [1, 2, 8, 9], [3, 10, 11]]
它们可用于预览原始图形(print('new_names:', g.vs.indices)
print('old_names:', g.vs['name'])
>>> new_names: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> old_names: [0, 1, 2, 3, 4, 5, 6, 7, 9, 13, 14, 16]
现在有所不同):
vertex_label
最后,您需要使用旧的顶点名称来修复输出。可以这样完成:
pal = ig.drawing.colors.ClusterColoringPalette(len(i)) #passing a number of colors
color = pal.get_many(i.membership) ##a list of color codes for each vertex
ig.plot(g, bbox = (200, 100), vertex_label=g.vs['name'],
vertex_color = color, vertex_size = 12, vertex_label_size = 8)