基于Pandas实现特定行组合数值求和及重复颜色去重统计
需求1:按Name列分组对数值列求和
原始DataFrame定义
import pandas as pd import numpy as np df1 = pd.DataFrame({'Name' : ['Jake', 'Nate', '', 'Alex', '', 'Max', 'Nate', 'Jake'], 'Color' : ['', 'red;blue', 'blue;pink', 'green;blue;red', '', '', 'blue', 'red;yellow'], 'Value_1' : [1211233.419, 4007489.726, 953474.6894, np.NaN, 1761987.704, 222600361, 404419.2243, 606066.067 ], 'Value_2' : [np.NaN, 1509907.457, 4792269.911, 43486.59312, np.NaN, np.NaN, 2066645.251, 60988660.37], 'Value_3' : [1175299.998, np.NaN, 1888559.459, np.NaN, 444689.0177, 405513.0572, 343704.0269, 2948494.383]})
原始数据预览:
Name Color Value_1 Value_2 Value_3 0 Jake 1.211233e+06 NaN 1.175300e+06 1 Nate red;blue 4.007490e+06 1.509907e+06 NaN 2 blue;pink 9.534747e+05 4.792270e+06 1.888559e+06 3 Alex green;blue;red NaN 4.348659e+04 NaN 4 1.761988e+06 NaN 4.446890e+05 5 Max 2.226004e+08 NaN 4.055131e+05 6 Nate blue 4.044192e+05 2.066645e+06 3.437040e+05 7 Jake red;yellow 6.060661e+05 6.098866e+07 2.948494e+06
实现代码
过滤Name为空的记录后,按Name分组对数值列求和:
result1 = df1[df1['Name'] != ''].groupby('Name')[['Value_1', 'Value_2', 'Value_3']].sum().reset_index()
预期结果
Name Value_1 Value_2 Value_3 0 Alex NaN 4.348659e+04 NaN 1 Jake 1.817299e+06 6.098866e+07 4.123794e+06 2 Max 2.226004e+08 NaN 4.055131e+05 3 Nate 4.411909e+06 3.576553e+06 3.437040e+05
需求2:按Name和拆分后的Color分组求和(含重复Color特殊处理)
基础场景要求
仅保留同时存在Name和Color的记录,拆分Color列后按Name+Color分组求和,基础场景预期结果:
Name Color Value_1 Value_2 Value_3 0 Alex green NaN 4.348659e+04 NaN 1 Alex blue NaN 4.348659e+04 NaN 2 Alex red NaN 4.348659e+04 NaN 3 Jake red 6.060661e+05 6.098866e+07 2.948494e+06 4 Jake yellow 6.060661e+05 6.098866e+07 2.948494e+06 5 Nate red 4.007490e+06 1.509907e+06 NaN 6 Nate blue 4.411909e+06 3.576553e+06 3.437040e+05
特殊场景说明
当同一行的Name对应重复Color(如red;red、b;b;b;y;y)时,需保证同一行内的重复Color仅统计一次:
- 示例输入:
Name color Value_1 Value_2 Value_3 Max red;red 1 1 1 Jake b;b;b;y;y 1 1 1 Max red 3 3 3
- 错误结果(重复Color多次统计):
Name color Value_1 Value_2 Value_3 Max red 5 5 5 Jake b 3 3 3 Jake y 2 2 2
- 预期结果(同一行重复Color仅算一次):
Name color Value_1 Value_2 Value_3 Max red 4 4 4 Jake b 1 1 1 Jake y 1 1 1
通用实现代码
以下代码同时满足基础场景和特殊场景要求:
# 1. 过滤Name或Color为空的无效记录 filtered_df = df1[(df1['Name'] != '') & (df1['Color'] != '')].copy() # 2. 对每行的Color拆分后去重,再重新拼接 filtered_df['Color'] = filtered_df['Color'].apply(lambda x: ';'.join(list(set(x.split(';'))))) # 3. 将去重后的Color拆分为多行 exploded_df = filtered_df.assign(Color=filtered_df['Color'].str.split(';')).explode('Color') # 4. 按Name和Color分组求和 result2 = exploded_df.groupby(['Name', 'Color'])[['Value_1', 'Value_2', 'Value_3']].sum().reset_index()
代码说明
- 过滤无效记录:只保留同时有Name和Color的行,排除空值干扰;
- 行内Color去重:对每行的Color字符串拆分后去重,避免同一行重复Color被多次拆分;
- 拆分Color为多行:实现Name与单个Color的一一对应;
- 分组求和:按Name+Color分组,对数值列求和得到最终结果。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

