我有一个如下所示的数据框:
id name
0 12 molly
1 12 james
2 10 adam
3 8 susan
4 10 molly
5 9 pete
6 2 james
7 10 Bob
8 8 james
9 2 adam
10 12 Gary
我想基于id号创建'pairwise'列,其中cols'name_x'和'name_y',其中两个名称的id都是这样的:
id name_x name_y
0 12 molly james
1 12 molly gary
2 12 gary james
3 10 adam molly
4 10 adam Bob
5 10 molly Bob
6 8 susan james
7 2 james adam
我知道某处必须有解决方案,但我无法想出找到它的正确术语!
答案 0 :(得分:1)
让我们使用itertools.combiniations:
from itertools import combinations
df.groupby('id')['name']\
.apply(lambda x: pd.DataFrame((i for i in combinations(x.values,2))))\
.reset_index().drop('level_1',axis=1)\
.rename(columns={0:'name_x',1:'name_y'})
输出:
id name_x name_y
0 2 james adam
1 8 susan james
2 10 adam molly
3 10 adam Bob
4 10 molly Bob
5 12 molly james
6 12 molly Gary
7 12 james Gary
答案 1 :(得分:0)
此解决方案的第一步是使用merge
,删除name_x == name_y
-
df = df.merge(df, on='id').query('name_x != name_y')
现在,如果你打印这个,你会注意到这个中间结果中有很多重复的条目。例如,molly - james
和james - molly
出现在两个不同的位置。如果顺序无关紧要,请使用np.sort
和drop_duplicates
-
df[['name_x', 'name_y']] = np.sort(df.iloc[:, 1:], axis=1)
df = df.drop_duplicates().reset_index(drop=True)
df
id name_x name_y
0 12 james molly
1 12 Gary molly
2 12 Gary james
3 10 adam molly
4 10 Bob adam
5 10 Bob molly
6 8 james susan
7 2 adam james
答案 2 :(得分:0)
itertools.combinations
的另一个选项如下:
In [30]: from itertools import combinations
In [31]: df.groupby('id').name.apply(lambda group: list(combinations(group, 2))).apply(pd.Series).stack().reset_index(level=1, drop=True).apply(pd.Series).rename(columns={0: 'name_x', 1: 'name_y'})
Out[31]:
name_x name_y
id
2 james adam
8 susan james
10 adam molly
10 adam Bob
10 molly Bob
12 molly james
12 molly Gary
12 james Gary