如何在Pandas中按组展平DataFrame并创建新列
解决Pandas数据从长格式转宽格式的问题
我来帮你搞定这个数据重塑的需求!你需要把每个家庭的多条记录合并成一行,同时按顺序展示每个孩子的年龄,还得保留父亲的年龄。下面是具体的实现步骤:
1. 准备原始数据
首先我们先把你提供的DataFrame创建出来:
import pandas as pd # 原始数据 df = pd.DataFrame({ 'Id_household': [1,1,1,1,2,3,3], 'Age_Father': [30,30,30,30,27,40,40], 'Age_child': [2,4,4,1,4,14,18] })
2. 对每个家庭的孩子年龄排序并编号
观察你想要的结果,每个家庭的孩子年龄是按从小到大排列的,所以我们先对每个家庭的孩子年龄排序,然后给每个孩子分配一个序号(1、2、3...):
# 按家庭分组,对孩子年龄升序排序 df_sorted = df.sort_values(['Id_household', 'Age_child']) # 给每个家庭内的排序后的孩子添加序号(从1开始) df_sorted['child_num'] = df_sorted.groupby('Id_household').cumcount() + 1
3. 转成宽格式并整理列名
接下来用pivot_table把长格式转成宽格式,同时给列名改成你想要的Age_child_1、Age_child_2这种形式:
# 转宽格式,以家庭ID为索引,孩子序号为列,值为孩子年龄 wide_df = df_sorted.pivot_table( index='Id_household', columns='child_num', values='Age_child', aggfunc='first' # 每个序号对应唯一的年龄,用first即可 ).rename(columns=lambda x: f'Age_child_{x}')
4. 添加父亲年龄并调整列顺序
因为每个家庭的父亲年龄是固定的,我们把它合并到宽格式的DataFrame里,并且放到最前面:
# 获取每个家庭的父亲年龄(取第一个值即可,因为同一家庭的父亲年龄都一样) wide_df['Age_Father'] = df.groupby('Id_household')['Age_Father'].first() # 调整列顺序,把Age_Father放到最左边 wide_df = wide_df[['Age_Father'] + [col for col in wide_df.columns if col != 'Age_Father']]
最终结果
运行完上面的代码后,你就能得到和预期完全一致的结果:
Age_Father Age_child_1 Age_child_2 Age_child_3 Age_child_4 Id_household 1 30 1.0 2.0 4.0 4.0 2 27 4.0 NaN NaN NaN 3 40 14.0 18.0 NaN NaN
如果不需要把Id_household作为索引,只需要加上wide_df = wide_df.reset_index()就能把它变回普通列啦。
内容的提问来源于stack exchange,提问作者Adrien Pacifico
相关产品推荐
相关产品推荐

