Python 数据帧中多列的普通最小二乘回归
我试图找到一种方法,在许多列(Z3以上)上迭代线性回归的代码。下面是名为df1的数据帧片段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
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产品就不那么漂亮了
isnp.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)