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
存在这样的 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