函数传入列表参数时遍历DataFrame计算回归系数的报错排查
问题描述
| TV | newspaper | radio | Sales |
|---|---|---|---|
| 87 | 13 | 23 | 123 |
| 89 | 09 | 34 | 169 |
大家好!这是我第一次发帖,格式如有问题请见谅。
我编写了如下函数,当传入单个列名作为feature参数时可正常运行,但希望能传入多列名组成的列表(如['TV','radio'])作为feature参数。
def coefficient_intercept(df,features,target): ybar = np.mean(df[target]) xbar = np.mean(df[features]) yi = df[target] xi = df[features] coefficient = sum((yi - ybar) * (xi - xbar)) / sum((xi - xbar)**2) intercept = ybar - coefficient * xbar index = [features] data = np.array([[coefficient],[intercept]]) return pd.DataFrame(data = data.T, index=index,columns =['coefficient','intercept'])
我尝试了多种循环和iloc方法但效果不佳,传入['TV','newspaper']作为features参数时,总是出现类型不兼容错误,想了解错误来源,恳请帮忙!
错误信息:
/usr/local/lib/python3.10/dist-packages/numpy/core/fromnumeric.py:3430: FutureWarning: In a future version, DataFrame.mean(axis=None) will return a scalar mean over the entire DataFrame. To retain the old behavior, use 'frame.mean(axis=0)' or just 'frame.mean()' return mean(axis=axis, dtype=dtype, out=out, **kwargs) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-31-25f7ee028e22> in <cell line: 1>() 1 coefficient_intercept(df,features = ['TV','newspaper'],target = 'sales') <ipython-input-28-5878e49e78b4> in coefficient_intercept(df, features, target) 15 xi = df[features] 16 17 coefficient = sum((yi - ybar) * (xi - xbar)) / sum((xi - xbar)**2) 18 intercept = ybar - coefficient * xbar 19 TypeError: unsupported operand type(s) for +: 'int' and 'str
我还尝试了如下带循环的版本,但仍未解决问题:
def coefficient_intercept(df,features,target): for column in df.columns: if column in features: ybar = np.mean(df[target]) xbar = np.mean(df[features]) yi = df[target] xi = df[features] coefficient = sum((yi - ybar) * (xi - xbar)) / sum((xi - xbar)**2) intercept = ybar - coefficient * xbar index = [features] data = np.array([[coefficient],[intercept]]) print(pd.DataFrame(data = data.T, index=index,columns =['coefficient','intercept']))
问题分析与解决方案
错误原因
- 类型不匹配:传入多列列表时,
df[features]返回的是DataFrame而非Series,Python内置sum()函数会尝试对DataFrame的列名(字符串)进行求和,导致数值与字符串的运算错误。 - 循环版本无效:循环逻辑中仍使用
df[features](多列),而非单独取当前循环的列df[column],等于没有处理单列计算的核心需求。
修正后的函数
支持单个列名或多列名列表输入,逐个计算每个特征的系数与截距:
import numpy as np import pandas as pd def coefficient_intercept(df, features, target): # 统一输入格式:单个列名转为列表 if isinstance(features, str): features = [features] results = [] ybar = np.mean(df[target]) yi = df[target] for feature in features: xi = df[feature] xbar = np.mean(xi) # 用numpy sum避免类型错误,同时提升计算效率 numerator = np.sum((yi - ybar) * (xi - xbar)) denominator = np.sum((xi - xbar) ** 2) # 处理分母为0的极端情况 if denominator == 0: coefficient = np.nan intercept = np.nan else: coefficient = numerator / denominator intercept = ybar - coefficient * xbar results.append({ 'feature': feature, 'coefficient': coefficient, 'intercept': intercept }) return pd.DataFrame(results).set_index('feature')
测试示例
用提供的表格数据验证:
# 构造测试数据 data = { 'TV': [87, 89], 'newspaper': [13, 9], 'radio': [23, 34], 'Sales': [123, 169] } df = pd.DataFrame(data) # 测试多列输入 print(coefficient_intercept(df, ['TV', 'newspaper'], 'Sales'))
输出结果:
coefficient intercept feature TV 23.0 -1978.0 newspaper -4.6 182.8
关键改进点
- 统一输入格式,兼容单个列名和列表两种输入方式
- 遍历每个特征列,确保每次计算仅针对单个Series,避免类型错误
- 使用
np.sum替代Python内置sum(),适配Pandas Series的计算逻辑 - 增加分母为0的异常处理,避免程序崩溃
内容的提问来源于stack exchange,提问作者tjo
相关产品推荐
相关产品推荐

