Python Pandas:如何基于其他列值生成新列?分组赋值报错解决
解决方法:根据客户ID和月份匹配填充对应total值
问题原因分析
你之前的代码报错是因为groupby()方法返回的是GroupBy分组对象,并非与原DataFrame行数匹配的数值序列。分组对象的长度是分组数量(1178个),远小于原数据行数(58779行),直接赋值自然会出现长度不匹配的错误。
正确实现思路
我们需要先构建「客户ID-月份」与total的映射表,再通过匹配映射表填充新列。以下是两种高效实现方式:
方法1:使用set_index+get构建映射
适合数据量中等的场景,代码简洁直观:
import pandas as pd # 构建客户ID+实际月份到total的映射表 lookup_table = df.set_index(['customer_id', 'Year-month_actual'])['total'] # 填充Total_month_1:匹配customer_id + Year-month_1对应的total df['Total_month_1'] = df.apply( lambda row: lookup_table.get((row['customer_id'], row['Year-month_1']), pd.NA), axis=1 ) # 同理填充Total_month_2 df['Total_month_2'] = df.apply( lambda row: lookup_table.get((row['customer_id'], row['Year-month_2']), pd.NA), axis=1 )
方法2:使用merge关联匹配
适合大数据量场景,性能更优:
# 提取用于匹配的临时表:客户ID、实际月份、对应total temp_df = df[['customer_id', 'Year-month_actual', 'total']].rename( columns={'Year-month_actual': 'target_month', 'total': 'Total_month_1'} ) # 关联匹配Total_month_1 df = df.merge( temp_df, left_on=['customer_id', 'Year-month_1'], right_on=['customer_id', 'target_month'], how='left' ).drop('target_month', axis=1) # 同理处理Total_month_2 temp_df = df[['customer_id', 'Year-month_actual', 'total']].rename( columns={'Year-month_actual': 'target_month', 'total': 'Total_month_2'} ) df = df.merge( temp_df, left_on=['customer_id', 'Year-month_2'], right_on=['customer_id', 'target_month'], how='left' ).drop('target_month', axis=1)
验证结果
运行上述代码后,会得到你预期的输出效果:每条记录的Total_month_1会填充该客户在Year-month_1对应月份的total值,无匹配时显示pd.NA(可根据需求替换为'Na'或其他值)。
内容的提问来源于stack exchange,提问作者Marco Marcellino
相关产品推荐
相关产品推荐

