You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数传入列表参数时遍历DataFrame计算回归系数的报错排查

问题描述
TVnewspaperradioSales
871323123
890934169

大家好!这是我第一次发帖,格式如有问题请见谅。

我编写了如下函数,当传入单个列名作为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']))

问题分析与解决方案

错误原因

  1. 类型不匹配:传入多列列表时,df[features]返回的是DataFrame而非Series,Python内置sum()函数会尝试对DataFrame的列名(字符串)进行求和,导致数值与字符串的运算错误。
  2. 循环版本无效:循环逻辑中仍使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 19:52:41