Pandas dataframe 条件内部连接自身

Pandas dataframe conditional inner join with itself

我正在寻找一种方法,根据条件将数据框的列与其自身进行内部连接。 我有一个由两列组成的大型数据框,'Group' 和 'Person'。现在我想创建第二个数据框,它为同一组中的每个人元组都有一个条目。第一个数据框:

    Group | Person
    a1    | p1
    a1    | p2
    a1    | p3
    a1    | p4
    a2    | p1

输出:

    Person1 | Person2 | Weight
    p1      | p2      | 1
    p1      | p3      | 1
    p1      | p4      | 1
    p2      | p3      | 1
    p2      | p4      | 1
    p3      | p4      | 1

如果一个人的元组是多个组的一部分,则权重会增加。 到目前为止,我已经能够基于一个子数据框和两个 for 循环创建一个简单的实现。有没有更优雅、更重要的 faster/builtin 方法来做到这一点?

到目前为止我的实现:

    group = principals.iloc[i,0]

    sub = principals.loc[principals['Group'] == group]
    
    for j in range(len(sub)-1):
        for k in range (j+1,len(sub)):
            #check if tuple exists -> update or create new entry

我在想,有没有类似SQLinner join的功能,基于组相同的条件,然后人对人的join。在那种情况下我可以处理双 p1|p1 条目...

非常感谢

combinations 会给你你正在寻找的元组对。一旦你得到这些,你就可以将元组组合分解成行。然后你的 weight 是每对的组大小 - 在这种情况下是 1 因为它们都只存在于一个组中。

import pandas as pd
import numpy as np
from itertools import combinations

df = pd.DataFrame({'Group': ['a1', 'a1', 'a1', 'a1', 'a2'],
 'Person': ['p1', 'p2', 'p3', 'p4', 'p1']})

df = (
    df.groupby('Group')['Person']
      .apply(lambda x: tuple(combinations(x,2)))
      .explode()
      .dropna()
      .reset_index()
)

df['Weight'] = df.groupby('Person').transform(np.size)
df[['Person1','Person2']] = df['Person'].apply(pd.Series)

df = df[['Person1','Person2','Weight']]

print(df)

输出

  Person1 Person2  Weight
0      p1      p2       1
1      p1      p3       1
2      p1      p4       1
3      p2      p3       1
4      p2      p4       1
5      p3      p4       1