Pandas: 如何将具有相同列值的多行组合起来并创建一个涵盖所有可能性的新 Dataframe?

Pandas: How to combine several rows with the same column value and create a new Dataframe which covers all possibilities?

存在这样的 DataFrame:

id name age
0x0 Hans 32
0x0 Peter 21
0x1 Jan 42
0x1 Simon 25
0x1 Klaus 51
0x1 Franz 72

我的目标是创建一个 DataFrame,涵盖同一 ID内的任何可能组合

ID 0x0 的唯一可能是汉斯和彼得。由于ID 0x1存在四次,所以有六种可能的解决方案,如下table所示。

由于是举例,一个ID也可能存在3次、5次、7次、...次,或多或少的可能性。

id name0 age0 name1 age1
0x0 Hans 32 Peter 21
0x1 Jan 42 Simon 25
0x1 Jan 42 Klaus 51
0x1 Jan 42 Franz 72
0x1 Simon 25 Klaus 51
0x1 Simon 25 Franz 72
0x1 Klaus 51 Franz 72

使用组合,我已经可以涵盖可能性方面,但我正在失去每个名字的年龄。

import pandas as pd
from  itertools import combinations

data = pd.DataFrame({'id': ["0x0", "0x0", "0x1", "0x1", "0x1", "0x1"], 'name': ["Hans","Peter","Jan","Simon","Klaus","Franz"], 'age': [32, 21, 42, 25, 51, 72]})

df = (data.groupby('id')['name'].apply(lambda x: pd.DataFrame(list(combinations(x,2))))
        .reset_index(level=1, drop=True)
        .reset_index())
print(df)

核心 python itertools combinations 是解决方案。 merge() 得到 年龄

import itertools
df = pd.read_csv(io.StringIO("""id  name    age
0x0 Hans    32
0x0 Peter   21
0x1 Jan 42
0x1 Simon   25
0x1 Klaus   51
0x1 Franz   72"""), sep="\t")

df1 = (
df
    .groupby(["id"])["name"]
    .apply(lambda x: pd.DataFrame(itertools.combinations(list(x),2)))
    .reset_index()
    .merge(df, left_on=["id",0], right_on=["id","name"])
    .merge(df, left_on=["id",1], right_on=["id","name"], suffixes=("0","1"))
    .drop(columns=["level_1",0,1])
)

输出

  id  name0  age0  name1  age1
 0x0   Hans    32  Peter    21
 0x1    Jan    42  Simon    25
 0x1    Jan    42  Klaus    51
 0x1  Simon    25  Klaus    51
 0x1    Jan    42  Franz    72
 0x1  Simon    25  Franz    72
 0x1  Klaus    51  Franz    72