Python从含Height、Weight列的DataFrame计算BMI的函数报错排查
首先,你的错误TypeError: ("'type' object is not subscriptable", 'occurred at index 0')主要来自三个关键问题,我逐个给你拆解:
1. 函数参数处理完全错误
你写的df=pd.DataFrame这行代码,不是把传入的行数据赋值给df,而是把pandas的DataFrame类本身赋值给了变量。当你用data.apply(BMI, axis=1)时,pandas是把每一行的Series对象传入你的函数,但你却在操作pd.DataFrame这个类型,它当然不能用[]下标去访问列,所以直接触发了类型错误。
正确的做法是直接使用传入的参数——而且因为axis=1是逐行处理,参数其实是单行的Series,建议把参数名改成row更直观。
2. 平方运算符用错了
Python里的^是按位异或运算符,不是数学里的平方!计算平方必须用**2,不然你的BMI计算逻辑完全是错的,就算不报错,结果也毫无意义。
3. 额外提醒:单位问题
BMI的标准公式是「体重(kg) ÷ (身高(m))²」,如果你的身高数据单位是厘米,一定要先除以100转换成米,不然算出来的结果会是实际值的10000倍,完全不符合预期。
这里给你两种写法,优先推荐第一种(效率更高):
方法一:向量化计算(强烈推荐)
pandas最擅长的就是向量化运算,直接对整列操作,比逐行apply快几十倍,尤其是大数据量时差距明显:
import pandas as pd # 假设你的data是目标DataFrame,先处理身高单位(如果是厘米的话) data['BMI'] = data['Weight'] / (data['Height'] / 100) ** 2
方法二:修正后的apply写法
如果你一定要用apply来实现,调整后的函数如下:
import pandas as pd def calculate_bmi(row): # 转换身高单位(如果是厘米) height_in_m = row['Height'] / 100 return row['Weight'] / (height_in_m ** 2) # 生成BMI列 data['BMI'] = data.apply(calculate_bmi, axis=1)
apply本质是逐行遍历,底层是Python循环,而向量化运算直接调用pandas的C语言底层实现,在数据量较大时,效率会有数量级的差距,所以能用向量化就尽量不用apply。
内容的提问来源于stack exchange,提问作者David

