如何在Pandas中按Courses分组仅求和Fee列并保留其余列?
Pandas分组仅指定列求和并保留其余列的解决方法
问题场景
给定如下Pandas DataFrame:
import pandas as pd technologies = ({ 'Courses':["Spark","PySpark","Hadoop","Python","Pandas","Hadoop","Spark","Python"], 'Fee' :[22000,25000,23000,24000,26000,25000,25000,22000], 'Duration':['30days','50days','55days','40days','60days','35days','55days','50days'], 'Discount':[1000,2300,1000,1200,2500,1300,1400,1600] }) df = pd.DataFrame(technologies, columns=['Courses','Fee','Duration','Discount'])
需求:按Courses列分组,仅对Fee列求和,同时保留其余所有列并按对应逻辑处理(如Duration需将天数部分求和后拼接单位,Discount求和)。
此前尝试的问题:
- 执行
df.groupby('Courses').sum()会将所有数值列(Fee、Discount)都求和,且丢失非数值列(Duration) - 执行
df.groupby('Courses')['Fee'].sum()仅返回Fee的求和结果,无其他列
期望输出:
Fee Duration Discount Courses Hadoop 48000 90days 2300 Pandas 26000 60days 2500 PySpark 25000 50days 2300 Python 46000 90days 2800 Spark 47000 85days 2400
可行解决方法
方法1:使用groupby.agg()自定义各列处理逻辑
这是最通用的方案,可针对每一列指定独立的处理规则,适配多列场景:
# 定义Duration列的处理函数:提取天数求和后拼接单位 def calculate_total_duration(durations): total_days = sum(int(dur.replace('days', '')) for dur in durations) return f"{total_days}days" # 分组聚合,指定每列的处理方式 df_result = df.groupby('Courses').agg( Fee=('Fee', 'sum'), Duration=('Duration', calculate_total_duration), Discount=('Discount', 'sum') ).reset_index() # 将Courses设为索引(与期望输出格式一致) df_result = df_result.set_index('Courses') print(df_result)
如果原始DataFrame包含更多列,只需在agg()的参数中添加对应的列名和处理规则即可,例如:
- 数值列求均值:
Score=('Score', 'mean') - 字符串列拼接:
Notes=('Notes', lambda x: ','.join(x))
方法2:分模块处理后合并结果
当列数量较多时,可分模块处理各列的聚合逻辑,再合并结果:
# 处理Fee列求和 fee_agg = df.groupby('Courses')['Fee'].sum().rename('Fee') # 处理Duration列 duration_agg = df.groupby('Courses')['Duration'].apply( lambda x: f"{sum(int(dur.replace('days', '')) for dur in x)}days" ).rename('Duration') # 处理Discount列求和 discount_agg = df.groupby('Courses')['Discount'].sum().rename('Discount') # 合并所有聚合结果 df_result = pd.concat([fee_agg, duration_agg, discount_agg], axis=1) print(df_result)
这种方式逻辑拆分清晰,便于维护不同列的处理逻辑。
内容的提问来源于stack exchange,提问作者iuuujkl
相关产品推荐
相关产品推荐

