【问题标题】:Ordinary Least Squares Regression for multiple columns in Pandas DataframePandas Dataframe 中多列的普通最小二乘回归
【发布时间】:2016-11-19 06:24:20
【问题描述】:

我正在尝试找到一种方法来迭代代码以在 Z3 以上的许多列上进行线性回归。这是名为 df1

的数据帧的 sn-p
    Time    A1      A2      A3      B1      B2      B3
1   1.00    6.64    6.82    6.79    6.70    6.95    7.02
2   2.00    6.70    6.86    6.92    NaN     NaN     NaN
3   3.00    NaN     NaN     NaN     7.07    7.27    7.40
4   4.00    7.15    7.26    7.26    7.19    NaN     NaN
5   5.00    NaN     NaN     NaN     NaN     7.40    7.51
6   5.50    7.44    7.63    7.58    7.54    NaN     NaN 
7   6.00    7.62    7.86    7.71    NaN     NaN     NaN

此代码仅返回非常 ONE 列的线性回归的斜率系数,并将该值连接到称为 series 的 numpy 系列,这是提取第一列的斜率的样子:

from sklearn.linear_model import LinearRegression

series = np.array([]) #blank list to append result

df2 = df1[~np.isnan(df1['A1'])] #removes NaN values for each column to apply sklearn function
df3 = df2[['Time','A1']]
npMatrix = np.matrix(df3)
X, Y = npMatrix[:,0], npMatrix[:,1]
slope = LinearRegression().fit(X,Y) # either this or the next line
m = slope.coef_[0]

series= np.concatenate((SGR_trips, m), axis = 0)

就目前而言,我正在使用这段代码,将“A1”替换为一个新的列名,一直到“Z3”,这是非常低效的。我知道有很多简单的方法可以用一些模块来做到这一点,但我的缺点是在时间序列中有所有这些中间 NaN 值,所以我似乎仅限于这种方法或类似的方法。

我尝试使用 for 循环,例如:

for col in df1.columns:

并替换“A1”,例如在代码中用 col 替换,但这似乎不起作用。

有什么方法可以更有效地做到这一点?

谢谢!

【问题讨论】:

    标签: python numpy pandas scipy scikit-learn


    【解决方案1】:

    对于少量(例如,少于数千)列,循环是一种不错的策略。没有看到你的实现,我不能说有什么问题,但这是我的版本,它有效:

    slopes = []
    
    for c in cols:
        if c=="Time": break
        mask = ~np.isnan(df1[c])
        x = np.atleast_2d(df1.Time[mask].values).T
        y = np.atleast_2d(df1[c][mask].values).T
        reg = LinearRegression().fit(x, y)
        slopes.append(reg.coef_[0])
    

    我已经稍微简化了你的代码以避免创建这么多临时的 DataFrame 对象,但它也应该可以按照你的方式正常工作。

    【讨论】:

    • 啊,这快把我逼疯了,感谢您的快速修复!
    【解决方案2】:

    一个(或三个)班轮

    time = df[['Time']]
    pd.DataFrame(np.linalg.pinv(time.T.dot(time)).dot(time.T).dot(df.fillna(0)),
                 ['Slope'], df.columns)
    

    稍微解释一下

    使用 OLS 的封闭形式

    在这种情况下,Xtime,我们将 time 定义为 df[['Time']]。我使用双括号来保留数据框及其两个维度。如果我做了单括号,我会得到一个系列和它的一个维度。那么点积就不那么漂亮了。

    np.linalg.pinv(time.T.dot(time)).dot(time.T)

    Ydf.fillna(0)。是的,我们可以一次完成一列,但为什么我们可以完全完成。你必须处理NaNs。你会如何想象与他们打交道?只在你有数据的时候这样做?这相当于在NaN 点中放置零。所以,我做到了。

    最后,我使用pd.DataFrame(stuff, ['Slope'], df.columns) 将所有斜坡包含在一个带有原始标签的位置。

    注意,我计算了 Time 对自身的回归斜率。为什么不?它就在那里。它的值为 1.0。伟大的!我可能做对了!

    【讨论】:

    • 效果很好。谢谢一百万!
    猜你喜欢
    • 2013-10-11
    • 2015-02-12
    • 2010-12-19
    • 2021-08-14
    • 1970-01-01
    • 2014-07-31
    • 2017-12-11
    • 2015-04-13
    • 2015-05-15
    相关资源
    最近更新 更多