【问题标题】:Dataframe with intersection among rows in pandas dataframe?熊猫数据框中的行之间有交集的数据框?
【发布时间】:2021-08-24 23:58:56
【问题描述】:

我在 pandas 数据框中遇到了挑战。 基本上,我有 2 列。在第一个中,我有 3 个不同的班级,在第二个中,我列出了该科目的学生名单。示例如下:

df = pd.DataFrame({'Class': ['1A', '2B', '2C'],
                    'Students': [['Alice', 'Philips', 'John'],
                                 ['Philips', 'John', 'Anna', 'William'],
                               ['Arthur', 'Alice', 'Anna', 'William']]
                  })

我想要第二个数据框,其中包含不止一个班级的学生人数。也就是说,类之间的交集,如下

result= pd.DataFrame({'Comparison': ['1A-2B','1A-2C', '2B-2C'],
                      'Intersection size': [2, 1, 2]})

感谢您的帮助和关注!

【问题讨论】:

标签: python pandas intersection


【解决方案1】:
import pandas as pd
import itertools

df = pd.DataFrame({'Class': ['1A', '2B', '2C'],
                    'Students': [['Alice', 'Philips', 'John'],
                                 ['Philips', 'John', 'Anna', 'William'],
                               ['Arthur', 'Alice', 'Anna', 'William']]
                  })
  1. 组合:生成所有列的组合。使用 itertools。
col=list(itertools.combinations(df.Class,2))  
> col  Out[68]:
> [('1A','2B'), ('1A', '2C'), ('2B', '2C')]
  1. explode:形成结构化数据框

df1=df.explode('Students')

  1. 写一个for
d={}
for c in col:
    tmp=df1[(df1['Class']==c[0]) | (df1['Class']==c[1])]
    count=len(tmp)-tmp.Students.nunique()
    d[str(c[0])+'-'+str(c[1])]=count

字典d有你想要的:

d
Out[71]: {'1A-2B': 2, '1A-2C': 1, '2B-2C': 2}

【讨论】:

    【解决方案2】:

    您可以尝试以下方法:

    import pandas as pd
    
    df = pd.DataFrame({
        'Class': ['1A', '2B', '2C'],
        'Students': [['Alice', 'Philips', 'John'],
                     ['Philips', 'John', 'Anna', 'William'],
                     ['Arthur', 'Alice', 'Anna', 'William']]
    })
    
    ddf = df.explode("Students")
    ddf = pd.crosstab(ddf["Students"], ddf["Class"])
    A = ddf.values
    result = pd.DataFrame(A.T @ A, index=ddf.columns, columns=ddf.columns)
    print(result)
    

    它给出:

    Class  1A  2B  2C
    Class            
    1A      3   2   1
    2B      2   4   2
    2C      1   2   4
    

    每行和每列的交集给出了参加这两个课程的学生人数。对角线条目给出了每个班级的学生人数。

    如果您想获得一个仅列出具有非零交集值的不同类组合的数据框,那么以下应该可行:

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({
        'Class': ['1A', '2B', '2C'],
        'Students': [['Alice', 'Philips', 'John'],
                     ['Philips', 'John', 'Anna', 'William'],
                     ['Arthur', 'Alice', 'Anna', 'William']]
    })
    
    ddf = df.explode("Students")
    ddf = pd.crosstab(ddf["Students"], ddf["Class"])
    A = ddf.values
    result = pd.DataFrame(np.tril(A.T @ A, k=-1).T,
                          index=ddf.columns,
                          columns=ddf.columns).stack()
    result.index = result.index.map(lambda x: f"{x[0]}-{x[1]}")
    result[result > 0]
    

    它给出:

    1A-2B    2.0
    1A-2C    1.0
    2B-2C    2.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-23
      • 2017-03-24
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2015-08-27
      • 2021-06-02
      • 1970-01-01
      相关资源
      最近更新 更多