Python Pandas遍历列计算分组累计求和报错求助
问题解决:DataFrame中用变量调用列的AttributeError问题
原始数据
a,b,c,d x,3,4,8 x,4,4,7 x,8,8,8 y,6,6,2 y,5,1,3 y,6,2,1 y,6,8,6 z,4,6,3 z,2,8,6 z,9,9,3 z,2,8,6 z,9,9,3
需求说明
- 循环筛选列
a中的每个唯一值(x、y、z) - 对筛选后的数据,分别计算列
b、c、d的累计求和,例如x对应的b列累计结果为3、7、15 - 将每个分组的累计求和结果存入新DataFrame用于后续计算
报错代码及问题
错误代码
Input["WinStartTime"].unique() Starts = Input["WinStartTime"].unique().tolist() Cols = [b, b] # 此处应为列名字符串列表,原代码存在错误 for I in Starts: InputLVPosU10 = (Input['WinStartTime'] == I) for J in Cols: Input["Tot"] = Input[InputLVPosU10].J.cumsum() # 报错核心位置 CS = pd.DataFrame(Input[InputLVPosU10].Tot) print (CS) CS = CS.reset_index(drop=True)
报错信息
AttributeError Traceback (most recent call last) in 10 # print(Input[InputLVPosU10].FinalinTicks.cumsum()) 11 ---> 12 Input["Tot"] = Input[InputLVPosU10].J.cumsum() #Inject Tot column w running total of FinalinTicks-Filtered and then totaled... 13 14 CS = pd.DataFrame(Input[InputLVPosU10].Tot) #CS,New dataframe - Running total of everything in 'InputLVPosU10' Based on the Time ~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\generic.py in __getattr__(self, name) 5065 if self._info_axis._can_hold_identifiers_and_holds_name(name): 5066 return self[name] -> 5067 return object.__getattribute__(self, name) 5068 5069 def __setattr__(self, name, value): AttributeError: 'DataFrame' object has no attribute 'J'
问题原因及解决方法
问题原因
- 使用
.调用列时,Python会将J识别为DataFrame的固定属性名,而非变量对应的列名,因此报错找不到J属性。 - 代码中
Cols = [b, b]错误,未使用字符串形式的列名,会导致变量未定义的额外报错。
修正后的代码
改用方括号索引实现变量调用列,同时修正列名列表:
import pandas as pd # 构造示例数据(如果已有Input可跳过此部分) data = """a,b,c,d x,3,4,8 x,4,4,7 x,8,8,8 y,6,6,2 y,5,1,3 y,6,2,1 y,6,8,6 z,4,6,3 z,2,8,6 z,9,9,3 z,2,8,6 z,9,9,3""" Input = pd.read_csv(pd.io.common.StringIO(data)) # 替换为实际分组列名(原代码WinStartTime对应示例中的a列) Starts = Input["a"].unique().tolist() Cols = ['b', 'c', 'd'] # 修正为字符串形式的目标列列表 # 初始化存储结果的DataFrame result_df = pd.DataFrame() for I in Starts: # 筛选当前分组数据并复制,避免修改原数据 group_data = Input[Input['a'] == I].copy() for J in Cols: # 用方括号索引实现变量调用列,计算累计求和 group_data[f'cum_{J}'] = group_data[J].cumsum() # 将当前分组结果合并到总数据 result_df = pd.concat([result_df, group_data], ignore_index=True) print(result_df)
代码说明
- 用
group_data[J]替代group_data.J,实现通过变量动态调用列名 - 新增
cum_{J}命名的累计列,避免覆盖原数据,同时区分不同列的累计结果 - 使用
pd.concat合并所有分组结果,便于后续处理
简化实现(推荐)
利用pandas内置分组功能,无需手动循环,效率更高:
import pandas as pd data = """a,b,c,d x,3,4,8 x,4,4,7 x,8,8,8 y,6,6,2 y,5,1,3 y,6,2,1 y,6,8,6 z,4,6,3 z,2,8,6 z,9,9,3 z,2,8,6 z,9,9,3""" df = pd.read_csv(pd.io.common.StringIO(data)) # 按列a分组,对b、c、d列分别计算累计求和 df[['cum_b', 'cum_c', 'cum_d']] = df.groupby('a')[['b', 'c', 'd']].cumsum() print(df)
内容的提问来源于stack exchange,提问作者Michael Reilley
相关产品推荐
相关产品推荐

