使用for循环处理CSV人口数据时遇AttributeError错误求助
解决添加人口变化百分比列时的AttributeError问题
嘿,我来帮你揪出代码里的问题,还会给你更高效的解决方案!
先说说你报错的根本原因
你看,你一开始把delta定义成了列表[],但进入循环后直接写了delta = df.population[n+1]/df.population[n]——这行代码把delta从列表类型直接覆盖成了单个的numpy.float64数值(也就是计算出来的人口比值)!之后再调用delta.append(i),自然会报错,因为numpy的浮点数对象根本没有append方法,只有列表才有这个方法呀~
除了这个核心问题,你的代码还有两个小坑:
- 循环范围
range(0,11210)会导致最后一次循环时n+1超出DataFrame的索引范围(如果你的df刚好有11210行,最后一行索引是11209,n+1就是11210,会报索引越界错误) - 你写的
delta.append(i)是把循环变量i添加进去,而不是你计算出来的人口变化值,这完全不符合需求
修正后的for循环版本
如果你坚持要用for循环实现,改成这样就没问题了:
# 单独用一个列表存变化值,别复用变量 delta_list = [] # 获取人口列的总行数,避免硬写11210这种魔法数字 total_rows = len(df['population']) # 循环到倒数第二行,这样i+1不会越界 for i in range(total_rows - 1): # 计算变化百分比:(下一年人口/本年人口 - 1) * 100,得到的是百分比值 # 如果你要的是变化倍数,去掉-1和*100就行 change_percent = (df['population'].iloc[i+1] / df['population'].iloc[i] - 1) * 100 delta_list.append(change_percent) # 最后一行没有下一年的数据,填充NaN(或者你想要的默认值,比如0) delta_list.append(float('nan')) # 把新列插入到population列的后面(也可以指定其他位置) pop_col_position = df.columns.get_loc('population') + 1 df.insert(pop_col_position, 'change', delta_list)
更推荐的Pandas矢量化方案
其实Pandas根本不推荐用for循环处理数据,尤其是数据量很大的时候,用矢量化操作速度快100倍都不止!用shift()方法就能一行搞定:
# 直接计算变化百分比,shift(-1)表示取下一行的人口数据 df['change'] = (df['population'].shift(-1) / df['population'] - 1) * 100 # 如果不想把新列放在最后,而是插入到population列后面,可以这么做 pop_col_idx = df.columns.get_loc('population') # 先把刚创建的change列删掉,再插入到指定位置 df.insert(pop_col_idx + 1, 'change', df.pop('change'))
额外注意事项
- 如果你的DataFrame不是连续的整数索引,一定要用
iloc按位置访问行,不然用df.population[i]可能会取错数据 - 如果人口数据有缺失值(NaN),计算出来的
change也会是NaN,你可以用df['change'].fillna(0)或者df.dropna(subset=['change'])来处理 - 确认你要的是变化百分比还是变化倍数:比如本年100,下年120,百分比是20%,倍数是1.2,按需调整公式
内容的提问来源于stack exchange,提问作者Eyal Marom
相关产品推荐
相关产品推荐

