Python 数据帧中多列的普通最小二乘回归

Python 数据帧中多列的普通最小二乘回归,python,numpy,pandas,scipy,scikit-learn,Python,Numpy,Pandas,Scipy,Scikit Learn,我试图找到一种方法,在许多列(Z3以上)上迭代线性回归的代码。下面是名为df1的数据帧片段 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

我试图找到一种方法,在许多列(Z3以上)上迭代线性回归的代码。下面是名为df1的数据帧片段

    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
此代码仅返回一列的线性回归的斜率系数,并将该值连接到一个名为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,但这似乎不起作用

有什么方法可以让我更有效地完成这项工作吗


谢谢大家!

对于数量不多(比如少于数千)的列来说,循环是一种不错的策略。在没有看到您的实现的情况下,我不能说有什么问题,但这是我的版本,它可以工作:

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
对象,但它也可以按您的方式工作。

一行(或三行)

经过一点解释就崩溃了 使用OLS的闭合形式

在这种情况下,
X
time
,我们将
time
定义为
df[['time']]
。我使用了双括号来保存数据帧及其二维。如果我用单括号,我会得到一个系列和它的一维。那么dot产品就不那么漂亮了

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

Y
df.fillna(0)
。是的,我们可以一次做一个专栏,但为什么我们可以一起做呢。您必须处理
NaN
s。你会怎么处理他们?只是在你有数据的时候才这么做?这相当于在
NaN
点中放置零。所以,我做到了

最后,我使用
pd.DataFrame(stuff,['Slope'],df.columns)
将所有坡度和原始标签放在一个地方


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

效果很好。万分感谢!啊,这让我发疯了,谢谢你的快速修复!
time = df[['Time']]
pd.DataFrame(np.linalg.pinv(time.T.dot(time)).dot(time.T).dot(df.fillna(0)),
             ['Slope'], df.columns)