pandas合并CSV后groupby求均值时报Wavelength Grouper非1维错误
ValueError: Grouper for 'Wavelength' not 1-dimensional 我正尝试使用pandas的.groupby()与.mean()方法对名称相似的列计算平均值,但运行时提示值非1维。
报错信息
ValueError: Grouper for 'Wavelength' not 1-dimensional
我已参照StackOverflow上相关问题的排查方法,验证当前DataFrame并非MultiIndex多索引:使用.columns.get_level_values(1)校验时,传入参数0可正常输出列名,传入参数1会提示仅存在1个层级,且通过type(df)校验也确认不是MultiIndex;另有StackOverflow回答建议修改列名,但该操作不符合我的需求,因为我需要用该脚本批量处理大量结构相似的文件。
我的疑问
如果不是MultiIndex索引导致的问题,数据为什么会出现非1维的情况?要如何修复代码,才能正常使用.groupby()和.mean()计算平均值?
代码片段
final_list = [] for i in np.arange(0, len(tb_avg)): # tb_avg 是存在重复的.csv文件名列表,文件名为"parameters_A"格式,后缀最多到"_E" file_list = [] for j in np.arange(0, int(tb_avg[i][1])): file_list.append(tb_avg[i][0] + end[j]) # 此处拼接_A.csv到_E.csv后缀补全文件名 working = pd.concat([pd.read_csv(f) for f in file_list], ignore_index=False, axis = 1) working = working.drop(['Wavelength.1'], axis=1) working = working.drop(index=0) working = working.groupby(by='Wavelength') # 代码在此处运行失败
示例数据
Wavelength S2c S2 Wavelength S2c 1 1100 5.09596043300629E-4 4.538E-4 1100 -2.21895500564575E-5 2 1110 3.50619777159691E-4 3.1748E-4 1110 2.84931027173996E-5 3 1120 6.16795350761414E-4 5.6608E-4 1120 -1.23864640111923E-4 4 1130 4.80301692390442E-4 4.456E-4 1130 -2.04537812271118E-4 5 1140 4.28569921140671E-4 4.0088E-4 1140 -2.3310064260006E-4 S2 Wavelength S2c S2 Wavelength 1 -1.976E-5 1100 5.1777114068985E-4 4.6108E-4 1100 2 2.58E-5 1110 6.66738603587151E-4 6.0372E-4 1110 3 -1.1368E-4 1120 3.66494637122154E-4 3.3636E-4 1120 4 -1.8976E-4 1130 6.91522337903976E-4 6.4156E-4 1130 5 -2.1804E-4 1140 4.32760686683655E-4 4.048E-4 1140 S2c S2 Wavelength S2c S2 1 -8.76127882289886E-4 -7.802E-4 1100 4.59871687202454E-4 4.0952E-4 2 -6.62276892929077E-4 -5.9968E-4 1110 5.10048626317978E-4 4.6184E-4 3 -8.10393778409958E-4 -7.4376E-4 1120 5.5015600004673E-4 5.0492E-4 4 -7.0902704949379E-4 -6.578E-4 1130 3.71091262693405E-4 3.4428E-4 5 -9.123467638731E-4 -8.534E-4 1140 3.56086782412529E-4 3.3308E-4
提前感谢各位的帮助!
问题解答
报错核心原因
你的索引校验结果正确,这个报错和MultiIndex完全无关,根源是单层列索引下存在多个完全重名的Wavelength列。
你按axis=1横向拼接多个csv时,每个源文件都自带Wavelength列,pandas横向拼接不会自动给同名列加后缀,最终生成的DataFrame会存在多个列名完全为Wavelength的列。执行groupby(by='Wavelength')时,pandas按列名匹配到了多列,返回的是二维表格结构,不符合groupby要求的一维分组键,因此触发非1维的报错。
可通过以下代码快速验证问题:
working.loc[:, 'Wavelength'].ndim
如果返回值大于1,就说明按Wavelength列名取到了多列。你之前手动删除Wavelength.1的操作没有生效,是因为当前拼接后的列里根本没有这个名称的列,所有重复的波长列名直接为Wavelength。
修复方案
结合你批量处理文件的需求,不需要修改原始列名,只要处理掉重复的波长列即可:
- 确认所有
Wavelength列的数值按行完全对齐(从示例数据可验证是对齐的),提取第一个Wavelength列作为统一分组键 - 删除所有其余重名的
Wavelength列 - 再执行分组求平均操作
修改后的完整代码片段:
final_list = [] for i in np.arange(0, len(tb_avg)): file_list = [] for j in np.arange(0, int(tb_avg[i][1])): file_list.append(tb_avg[i][0] + end[j]) working = pd.concat([pd.read_csv(f) for f in file_list], ignore_index=False, axis=1) # 提取第一个Wavelength列作为分组键 wl_group_key = working.loc[:, 'Wavelength'].iloc[:, 0] # 删除所有重名的Wavelength列 working = working.drop(columns=working.columns[working.columns == 'Wavelength']) # 将提取的波长列插回DataFrame working.insert(0, 'Wavelength', wl_group_key) working = working.drop(index=0) # 此时Wavelength为单列,可正常执行分组求平均 averaged_result = working.groupby(by='Wavelength').mean() final_list.append(averaged_result)
如果需要对不同文件的同名数值列(S2c/S2)合并求总平均,可在插入波长列后新增一行:
# 对同名列按行求平均,合并多文件的测量值 working = working.groupby(level=0, axis=1).mean()
内容的提问来源于stack exchange,提问作者Luke Teo

