pandas遍历DataFrame列表应用公式报无len()属性错误
问题描述
现有如下测试DataFrame:
import pandas as pd import numpy as np from numpy import rec, nan df1=pd.DataFrame.from_records(rec.array([(202101, 100.0, nan), (202102, 110.0, nan), (202103, 115.0, nan), (202104, 118.0, nan), (202105, 123.0, nan), (202106, 126.0, nan), (202107, 130.0, nan), (202108, 133.0, nan), (202109, 136.0, nan), (202110, 139.0, nan), (202111, 144.0, nan), (202112, 148.0, nan), (202201, 150.0, 50.0), (202202, 152.0, 38.2), (202203, 154.0, 33.9), (202204, nan, 30.0), (202205, nan, 25.0), (202206, nan, 20.0)], dtype=[('yyyymm', '<i8'), ('rev', '<f8'), ('yoy_pct_rev', '<f8')])) df1.set_index('yyyymm')
其中rev为营收字段,yoy_pct_rev为12个月同比变化率字段。已知2022年4-6月的同比增速,需要预测这3个月的营收值。
针对单个DataFrame使用for循环计算时,代码可正常运行,仅会出现yyyymm索引转为普通列的情况,对应代码如下:
for i in range(12,len(df1.index)): df1.iloc[i, 1] = df1.iloc[i-12, 1]*((df1.iloc[i,2]/100)+1) df1
由于存在多个行列结构完全一致、仅rev和yoy_pct_rev取值不同的DataFrame需要做相同计算,因此将DataFrame存入列表后执行遍历计算,对应代码如下:
my_list=[df1] for i in range(12,len(my_list.index)): my_list.iloc[i, 0] = my_list.iloc[i-12,0]*((my_list.loc[i,1]/100)+1) df1
运行时触发报错:object of type 'builtin_function_or_method' has no len(),需要定位代码问题。
错误原因
代码共有3处问题:
- 混淆了Python列表和pandas DataFrame的对象类型:
my_list是普通Python列表,不是DataFrame,没有.index属性、也没有.iloc/.loc索引方法。写len(my_list.index)时,Python会把index识别为列表内置的index()查找方法,无法对方法对象求长度,直接触发当前报错。 - 缺少两层遍历逻辑:列表中存储了多个DataFrame,需要先遍历取出列表中的每个DataFrame对象,再针对单个DataFrame执行营收填充计算,不能直接对列表对象调用pandas专属方法。
- 列索引取值错误:原单表逻辑中
rev是第2列(位置索引为1)、yoy_pct_rev是第3列(位置索引为2),列表版代码错将列索引写为0和1,即使解决前两个问题也会取错字段,导致计算结果错误。
修正后代码
my_list = [df1] # 可继续往列表中添加其他结构一致的待处理DataFrame # 第一层遍历:取出列表中每个DataFrame for df in my_list: # 第二层遍历:对单个DataFrame复用已经验证通过的填充逻辑 for i in range(12, len(df.index)): df.iloc[i, 1] = df.iloc[i-12, 1] * ((df.iloc[i, 2]/100) + 1) # 查看计算结果 df1
内容的提问来源于stack exchange,提问作者jack homareau
相关产品推荐
相关产品推荐

