假设我有一个 pandas 数据框,
id,date,school,name
1,2019-01-01,U,Doug
1,2021-01-01,U,Chris
1,2022-01-01,U,Chris
1,2023-01-01,U,Chris
1,2022-01-01,K,Liam
3,2024-01-01,M,Nancy
3,2024-01-01,M,Betty
我如何将其转换为格式,
id,school,name1,name2
1,U,Doug,Chris
1,K,Liam,''
3,M,Nancy,Betty
即我想按 ID 和学校进行分组,并为每个唯一的名称创建新列。
这是开始的代码。
import pandas as pd
d = {
'id': [1,1,1,1,2,3,3],
'date': ['2019-01-01', '2021-01-01', '2022-01-01', '2023-01-01', '2022-01-01', '2024-01-01', '2024-01-01'],
'school': ['U','U','U','U','K','M','M'],
'name': ['Doug','Chris','Chris','Chris','Liam','Nancy','Betty']
}
df = pd.DataFrame(d)
您可以使用此代码通过 ID 和学校获取唯一名称。 然后将每行列表中的每个元素移动到单独的列中,最后重命名这些列。
df_grouped = df.groupby(['id', 'school'])['name'].unique().apply(pd.Series) df_grouped = df_grouped.rename(columns={x: f"name{x+1}" for x in df_grouped.columns}) df_grouped
输出:
id | 学校 | 姓名1 | 名称2 |
---|---|---|---|
1 | 你 | 道格 | 克里斯 |
2 | K | 利亚姆 | NaN |
3 | M | 南希 | 贝蒂 |
请注意,我们的输出并不完全匹配,因为您的代码和您提供的示例之间 K 学校的 id 略有不匹配。
一个可能的解决方案:
cols = ['id', 'school']
g = df.groupby(cols)
out = (pd.concat([pd.concat(
[x.loc[:, cols].head(1).reset_index(drop=True),
pd.DataFrame(x['name'].unique()).T], axis=1) for _,x in g])
.reset_index(drop=True))
out.columns = [x if i <=1 else f'name{i-1}'
for i, x in enumerate(out.columns)]
输出:
id school name1 name2
0 1 U Doug Chris
1 2 K Liam NaN
2 3 M Nancy Betty