如何优化多DataFrame合并与函数参数?现有实现求改进方案
优化Pandas分组求和合并的实现方式
我已经成功生成了目标数据表,解决了之前的相关问题,但希望找到更简洁高效的实现方式。具体想请教:
- 能否将函数的多个列参数合并为单个参数传入?
- 是否需要先把CSV中的列转为列表,还是可以直接使用CSV列作为参数?
当前实现函数
def CHEGD_funct(countylist, Clist, Hlist, Elist, Glist, Dlist): Cdict = pd.DataFrame(list(zip(countylist, Clist)), columns = ['site', 'C']) Hdict = pd.DataFrame(list(zip(countylist, Hlist)), columns = ['site', 'H']) Edict = pd.DataFrame(list(zip(countylist, Elist)), columns = ['site', 'E']) Gdict = pd.DataFrame(list(zip(countylist, Glist)), columns = ['site', 'G']) Ddict = pd.DataFrame(list(zip(countylist, Dlist)), columns = ['site', 'D']) Cdf = Cdict.groupby('site').sum() Hdf = Hdict.groupby('site').sum() Edf = Edict.groupby('site').sum() Gdf = Gdict.groupby('site').sum() Ddf = Ddict.groupby('site').sum() dataframes = [Cdf, Hdf, Edf, Gdf, Ddf] mergedf = reduce(lambda left,right: pd.merge(left,right,on=['site'], how='outer'), dataframes).fillna('void') return mergedf
期望输出
type C H E G D site Angus 20 92 25 0 0 Angus / East Perthshire 1 8 3 0 0 Argyll 141 995 89 68 7 Ayrshire 71 336 68 17 9 Banffshire 7 86 19 0 0 Banffshire / Moray 2 10 0 0 0 Banffshire / South Aberdeenshire 1 3 0 0 0 Berwickshire 17 84 14 0 1 Caithness 43 374 202 36 5 Clyde Isles 29 142 38 9 5 Dumfriesshire 34 336 69 21 8 Dunbartonshire 38 85 19 10 2 East Inverness-shire & Nairn 162 879 318 45 10 East Inverness-shire & Nairn / Banffshire 1 8 4 0 0 East Inverness-shire / Moray 22 50 23 4 0 East Lothian 22 123 36 16 4 East Perthshire 31 149 79 7 5 East Ross 28 233 65 18 2 East Ross / East Inverness-shire 0 1 0 0 0 East Ross / East Sutherland 1 3 1 0 0 East Sutherland 34 208 71 8 4 Fifeshire 60 355 43 17 1 Kincardineshire 30 160 27 9 1 Kintyre 15 75 11 3 5 Kirkcudbrightshire 21 114 33 4 5 Lanarkshire 94 293 62 25 7 Lanarkshire / Peebleshire 3 7 0 2 0 Mid Ebudes 9 97 30 1 1 Mid Perthshire 46 378 176 26 8 Mid Perthshire / East Perthshire 3 9 3 1 0 Midlothain / Peebleshire 5 23 1 0 0 Midlothian 52 194 47 12 2 Midlothian / Berwickshire 8 20 3 2 1 Moray 60 311 77 11 2 Moray / East Inverness-shire & Nairn 5 14 11 0 1 North Aberdeenshire 38 211 55 10 1 North Ebudes 109 533 207 94 14 Orkney 50 230 126 23 1 Outer Hebrides 26 265 110 29 0 Peebleshire 66 339 114 25 10 Peebleshire / Selkirkshire 0 3 2 0 0 Renfrewshire 76 312 40 39 4 Roxburghshire 76 327 65 21 7 Selkirkshire 28 168 68 3 3 Shetland 57 426 195 13 7 South Aberdeenshire 159 791 320 64 21 South Aberdeenshire / East Perthshire 2 18 12 3 1 South Aberdeenshire / Kincardineshire 1 0 0 0 0 South Aberdeenshire / North Aberdeenshire 0 1 1 0 0 South Ebudes 36 172 38 4 4 Stirlingshire 33 121 26 5 4 West Inverness (Westerness) 0 0 1 0 0 West Inverness-shire 41 443 217 32 3 West Lothian 15 57 11 1 1 West Lothian / Stirlingshire 0 0 0 0 0 West Perthshire 18 107 23 0 1 West Ross 19 277 84 22 2 West Ross / West Sutherland 2 7 2 0 0 West Sutherland 78 610 196 58 4 Wigtownshire 9 46 17 2 1
优化方案
1. 直接传入DataFrame作为单个参数(推荐)
不需要拆分列成列表,直接读取CSV后把整个DataFrame传入函数,一步完成分组求和:
import pandas as pd def CHEGD_funct(df): # 按site分组,对C、H、E、G、D列求和,空值填充为'void' mergedf = df.groupby('site')[['C', 'H', 'E', 'G', 'D']].sum().fillna('void') # 插入type列(若需要保留该列) mergedf.insert(0, 'type', '') return mergedf # 使用示例:从CSV读取数据后直接调用 df = pd.read_csv('your_file.csv') result = CHEGD_funct(df)
2. 若必须传入列表参数,合并为单个字典
如果场景限制只能用列表传入,可将所有列打包成字典作为单个参数:
from functools import reduce import pandas as pd def CHEGD_funct(data_dict): countylist = data_dict['site'] cols = ['C', 'H', 'E', 'G', 'D'] dataframes = [] for col in cols: df = pd.DataFrame(list(zip(countylist, data_dict[col])), columns=['site', col]) dataframes.append(df.groupby('site').sum()) mergedf = reduce(lambda left, right: pd.merge(left, right, on=['site'], how='outer'), dataframes).fillna('void') mergedf.insert(0, 'type', '') return mergedf # 使用示例 data_dict = { 'site': countylist, 'C': Clist, 'H': Hlist, 'E': Elist, 'G': Glist, 'D': Dlist } result = CHEGD_funct(data_dict)
关键优化点
- 避免重复创建单个列的DataFrame,直接批量处理目标列,代码更简洁、效率更高
- 无需多次merge操作,
groupby.sum()会自动保留所有列的聚合结果 - 支持直接传入CSV读取的DataFrame,省去手动拆分列的繁琐步骤
内容的提问来源于stack exchange,提问作者Daisy
相关产品推荐
相关产品推荐

