【问题标题】:How to group all labels (index) which shares at least one "1" in the same column?如何对同一列中至少共享一个“1”的所有标签(索引)进行分组?
【发布时间】:2018-02-22 08:49:10
【问题描述】:

分组规则:

  • 在同一列中至少有一个“1”
  • 共享任意数量的公共行(参见示例)

例如:

   c0  c1  c2  c3
A   1   0   0   1
B   0   0   1   0
C   0   0   0   1
D   0   1   1   0
E   0   1   0   0

预期输出:

[[A, C], [B, D, E]]

如您所见,B 和 E 在列中不共享“1”,但它们有共同的“D”,因此应将所有 3 个分组

【问题讨论】:

  • B和E怎么在同一个组?
  • @omri_saadon 他们有共同点
  • 图形/网络需要这个吗?
  • 我建议您在问题中添加更多关于行分组规则的说明。
  • @omri_saadon,我添加了更多关于规则的解释,tnx 供建议

标签: python pandas numpy


【解决方案1】:

这是一个使用networkx的解决方案。

import networkx as nx
a = np.where(df.T, df.index, '').sum(axis=1)
g = [list(x) for x in a if len(x) > 1]
G = nx.Graph(g)
list(nx.connected_components(G))

[{'B', 'D', 'E'}, {'A', 'C'}]

【讨论】:

  • 我在[df.index[df[c].astype(bool)].tolist() for c in df.columns],这可能比这慢。
  • 非常感谢大家!
  • 使用@TedPetrou 的推演后,如果不想使用networkx,请参阅Merge lists that share common elements 替代方法
  • 这很好 +1。
【解决方案2】:

这样就可以实现你想要的:

import numpy as np
from itertools import combinations 
import networkx as nx

df
"""output:  
   1  2  3  4
0            
A  1  0  0  1
B  0  0  1  0
C  0  0  0  1
D  0  1  1  0
E  0  1  0  0
"""

df.index.tolist()
"""output:
['A', 'B', 'C', 'D', 'E']
"""
list(combinations(df.index.tolist(),2))

"""output : 
[('A', 'B'),
 ('A', 'C'),
 ('A', 'D'),
 ('A', 'E'),
 ('B', 'C'),
 ('B', 'D'),
 ('B', 'E'),
 ('C', 'D'),
 ('C', 'E'),
 ('D', 'E')]
"""
results = [x for x in list(combinations(df.index.tolist(),2)) if np.sum(df.loc[x[0],:].multiply(df.loc[x[1],:])) > 0]

results
"""output: 
[('A', 'C'), ('B', 'D'), ('D', 'E')]
"""
list(nx.connected_components(nx.Graph(results)))
"""output: 
[{'A', 'C'}, {'B', 'D', 'E'}]
"""

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多