如何使用pandas为groupby上的唯一值创建新列?

问题描述 投票:0回答:2

假设我有一个 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)
pandas group-by transform
2个回答
0
投票

您可以使用此代码通过 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 略有不匹配。


0
投票

一个可能的解决方案:

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
© www.soinside.com 2019 - 2024. All rights reserved.