【问题标题】:linear regression for timeseries python (numpy or pandas)时间序列python的线性回归(numpy或pandas)
【发布时间】:2015-11-26 10:41:50
【问题描述】:

我是 python 和一般编程的新手,所以请原谅任何简单的错误/应该是显而易见的事情。

我想做的很简单,我只想将线性趋势(一维多项式)拟合到一堆时间序列中,看看斜率是正还是负。现在我只是想让它在一个时间序列中工作。

问题:pandas 和 numpy 似乎都无法对日期时间进行回归。我的约会时间不规律(通常是每月 1 天,但不是同一天)所以不能使用Linear Regression from Time Series Pandas 中提出的建议

我的时间序列 csv 看起来像:

StationName,    year,   month,  day,    depth,  NO3-N,  PO4-P,  TotP,   TotN,
Kvarnbacken (Savaran),  2003,   2,  25, 0.5,    46, 9,  14, 451
Kvarnbacken (Savaran),  2003,   3,  18, 0.5,    64, 15, 17, 310
Kvarnbacken (Savaran),  2003,   3,  31, 0.5,    76, 7,  19, 566

到目前为止我所拥有的是

import datetime as dt
from scipy import stats
import numpy as np

# read in station csv file
data = pd.read_csv('Kvarnbacken (Savaran)_2003.csv')
data.head()
# set up dates to something python can recognize
data['date'] = pd.to_datetime(data.year*10000+data.month *
                          100+data.day, format='%Y%m%d')

我试过了

slope, intercept, r_value, p_value, std_err = stats.linregress(data.date,
                                                               data.TotP)

并得到错误 TypeError: ufunc add 不能使用类型为 dtype('

我也试过

coefP = np.polyfit(data.date, data.TotP, 1)
polyP = np.poly1d(coefP)
ys = polyP(data.date)
print 'For P: coef, poly'
print coefP
print polyP

并得到同样的错误。

我猜最简单的方法是做一些事情,我只计算自第一次测量以来的天数,然后只用 days_since 对总磷浓度 (totP) 进行回归,但我不确定最简单的方法,或者如果有另一个技巧。

【问题讨论】:

  • 您在做的事情对我来说似乎是错误的,因为两天之间的间隔不是恒定的(例如:12 月 31 日和 1 月 1 日之间)。你可以说第 0 天是你的第一次约会。然后将第一个日期减去每个日期并以天为单位进行转换。
  • 雨果你绝对正确。我并没有真正考虑过我的快速修复。
  • 评论 #1 不是一个好方法。如果你想做这样的事情,你应该把它转换成一些常用的单位。更像是 365*year + 30*month + days。尽管即使这样也不理想,因为年和月的天数不是固定的。请参阅答案以获得更好的方法。

标签: python numpy pandas statsmodels


【解决方案1】:

您可以通过以下方式将日期时间转换为天数。

data['days_since'] = (data.date - pd.to_datetime('2003-02-25') ).astype('timedelta64[D]')

        date  days_since
0 2003-02-25           0
1 2003-03-18          21
2 2003-03-31          34

现在你应该可以像上面那样回归了。

slope, intercept, r_value, p_value, std_err = stats.linregress(data.days_since, 
                                                               data.TotP)
slope, intercept
(0.1466591166477916, 13.977916194790488)

您可能还想考虑其他回归选项,例如 statsmodels 包,特别是如果您会经常做这种事情。 (注意 x 和 y 与 linregress 相比是相反的)

import statsmodels.formula.api as smf

smf.ols( 'TotP ~ days_since', data=data ).fit().params

Intercept     13.977916
days_since     0.146659

顺便说一句,这只是 statsmodels 输出的一小部分(使用 summary() 而不是 params 来获得额外的输出。

【讨论】:

  • 谢谢。我最终做了类似的事情,但被困在如何将“day_since”作为整数获取,astype 是一个不错的技巧。
猜你喜欢
  • 2015-08-06
  • 2020-09-30
  • 2016-07-21
  • 2020-04-16
  • 2014-08-30
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多