【问题标题】:How can I detect common elements lists and groupe lists with at least 1 common element?如何检测具有至少 1 个共同元素的共同元素列表和分组列表?
【发布时间】:2019-06-20 10:55:27
【问题描述】:

我有一个包含子列表或元素列表的 1 列(+索引)的数据框。 我想检测列表/子列表中的公共元素,并用至少 1 个公共元素对列表进行分组,以便只有没有任何公共元素的元素列表。 列表/子列表目前是这样的(例如 4 行):

                 Num_ID
Row1   [['A1','A2','A3'],['A1','B1','B2','C3','D1']]`

Row2   ['A1','E2','E3']

Row3   [['B4','B5','G4'],['B6','B4']]

Row4   ['B4','C9']

n 个没有共同元素的列表(前 2 个示例):

['A1','A2','A3','B1','B2','C3','D1','E2','E3']
['B4','B5','B6','C9','G4']

【问题讨论】:

标签: python pandas list networkx


【解决方案1】:

您可以为此使用NetworkXconnected_components 方法。以下是我如何处理这种适应 this 的解决方案:

import networkx as nx
from itertools import combinations, chain

df= pd.DataFrame({'Num_ID':[[['A1','A2','A3'],['A1','B1','B2','C3','D1']], 
                            ['A1','E2','E3'], 
                            [['B4','B5','G4'],['B6','B4']], 
                            ['B4','C9']]})

首先展平每个列表中的子列表:

L = [[*chain.from_iterable(i)] if isinstance(i[0], list) else i 
       for i in df.Num_ID.values.tolist()]

[['A1', 'A2', 'A3', 'A1', 'B1', 'B2', 'C3', 'D1'],
 ['A1', 'E2', 'E3'],
 ['B4', 'B5', 'G4', 'B6', 'B4'],
 ['B4', 'C9']]

鉴于列表/子列表有超过 2 个元素,您可以从每个子列表中获取所有长度为 2 的组合,并将它们用作网络边(注意边只能连接两个节点):

L2_nested = [list(combinations(l,2)) for l in L]
L2 = list(chain.from_iterable(L2_nested))

生成一个图,并使用 add_edges_from 将列表添加为图边。然后使用 connected_components,它会精确地为您提供图中连接组件集的列表:

G=nx.Graph()
G.add_edges_from(L2)
list(nx.connected_components(G))

[{'A1', 'A2', 'A3', 'B1', 'B2', 'C3', 'D1', 'E2', 'E3'},
 {'B4', 'B5', 'B6', 'C9', 'G4'}]

【讨论】:

  • 非常感谢。作为一个新手,我必须消化这里的所有概念,但对我的数据进行快速测试似乎非常好。您能否告诉我应该怎么做才能将结果集放入包含 Set1、Set2、Set3... 列的 Dataframe 中?再次感谢,您的快速回答给我留下了深刻的印象
  • 是的,只需构建一个数据框并转置@Jon1 pd.DataFrame(l).T。很高兴它有帮助:) 不要忘记您可以投票和接受答案,请参阅What should I do when someone answers my question?
  • 一切都很好。感谢永恒:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
相关资源
最近更新 更多