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
我正在寻找一种方法,根据条件将数据框的列与其自身进行内部连接。 我有一个由两列组成的大型数据框,'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