Pandas DataFrame - 基于唯一ID

时间:2018-01-10 21:21:47

标签: python pandas dataframe

我有一个如下所示的数据框:

        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

我知道某处必须有解决方案,但我无法想出找到它的正确术语!

3 个答案:

答案 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 - jamesjames - molly出现在两个不同的位置。如果顺序无关紧要,请使用np.sortdrop_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