Python 将数据帧上线性回归的日期转换为浮点

Python 将数据帧上线性回归的日期转换为浮点,python,pandas,time-series,Python,Pandas,Time Series,似乎OLS线性回归要在熊猫身上很好地工作,参数必须是浮动的。我从以下形式的csv(称为“gameAct.csv”)开始: date, city, players, sales 2014-04-28,London,111,1091.28 2014-04-29,London,100,1100.44 2014-04-28,Paris,87,1001.33 ... '\xef\xbb\xbf2014-04-28' 我想对销售如何依赖于日期进行线性回归(随着时间的推移,销售如何变化?)。我下面

似乎OLS线性回归要在熊猫身上很好地工作,参数必须是浮动的。我从以下形式的csv(称为“gameAct.csv”)开始:

date, city, players, sales

2014-04-28,London,111,1091.28

2014-04-29,London,100,1100.44

2014-04-28,Paris,87,1001.33

...
'\xef\xbb\xbf2014-04-28'
我想对销售如何依赖于日期进行线性回归(随着时间的推移,销售如何变化?)。我下面的代码的问题似乎是日期不是浮点值。我将非常感谢您对如何解决熊猫索引问题的帮助

我当前的(非工作,但正在编译代码):

当我改变城市值时,我得到R^2=1的结果,这是错误的。我还尝试了
index\u col=0,parse\u dates==True'
来定义
dataframe df
,但没有成功

我怀疑有更好的方法读取此类csv文件,以便对日期执行基本回归,也可以进行更一般的时间序列分析。感谢您的帮助、示例和资源

注意,使用上述代码,如果我将日期索引(针对给定城市)转换为数组,则该数组中的值的形式如下:

date, city, players, sales

2014-04-28,London,111,1091.28

2014-04-29,London,100,1100.44

2014-04-28,Paris,87,1001.33

...
'\xef\xbb\xbf2014-04-28'

如何对所有非销售参数进行AIC分析?(例如,结果可能是销售与日期和城市的关系最为线性)。

我不确定statsmodels的具体情况,但列出了python的所有日期/时间转换。它们并不总是一对一的,所以这是我经常使用的参考;-)

对于这种回归,我通常将日期或时间戳转换为数据开始后的整数天数

这很好地实现了这一点:

df = pd.read_csv('test.csv')
df['date'] = pd.to_datetime(df['date'])    
df['date_delta'] = (df['date'] - df['date'].min())  / np.timedelta64(1,'D')
city_data = df[df['city'] == 'London']
result = sm.ols(formula = 'sales ~ date_delta', data = city_data).fit()
此方法的优点是,您可以确定回归中涉及的单位(天),而自动转换可能会隐式使用其他单位,从而在线性模型中创建混乱的系数。它还允许您将在不同时间开始的多个销售活动的数据合并到您的回归中(假设您对活动的有效性感兴趣,这是活动天数的函数)。如果你有兴趣测量一年中的某一天的趋势,你也可以选择1月1日作为你的0。选择自己的0日期可以让您控制所有这些

还有证据表明statsmodels支持熊猫的时间序列。您也可以将其应用于线性模型:

另外,请注意: 您应该能够直接从csv中自动读取列名,就像我发布的示例代码一样。在您的示例中,我看到csv文件第一行中的逗号之间有空格,导致列名称像“date”。删除空格,自动读取csv标题就可以了

df.date.dt.total_seconds()
如果您日期的数据类型为
datetime64[ns]
,则该数据类型不起作用;这将返回秒数(浮点)。

将日期作为浮点年份获取 我更喜欢日期格式,它可以在没有上下文的情况下理解。因此,浮点年份表示法。 这里的好处是,该解决方案在
numpy
级别上工作-因此应该是快速的

import numpy as np
import pandas as pd

def dt64_to_float(dt64):
    """Converts numpy.datetime64 to year as float.

    Rounded to days

    Parameters
    ----------
    dt64 : np.datetime64 or np.ndarray(dtype='datetime64[X]')
        date data

    Returns
    -------
    float or np.ndarray(dtype=float)
        Year in floating point representation
    """

    year = dt64.astype('M8[Y]')
    # print('year:', year)
    days = (dt64 - year).astype('timedelta64[D]')
    # print('days:', days)
    year_next = year + np.timedelta64(1, 'Y')
    # print('year_next:', year_next)
    days_of_year = (year_next.astype('M8[D]') - year.astype('M8[D]')
                    ).astype('timedelta64[D]')
    # print('days_of_year:', days_of_year)
    dt_float = 1970 + year.astype(float) + days / (days_of_year)
    # print('dt_float:', dt_float)
    return dt_float

if __name__ == "__main__":

    dates = np.array([
        '1970-01-01', '2014-01-01', '2020-12-31', '2019-12-31', '2010-04-28'],
        dtype='datetime64[D]')

    df = pd.DataFrame({
        'date': dates,
        'number': np.arange(5)
        })

    df['date_float'] = dt64_to_float(df['date'].to_numpy())
    print('df:', df, sep='\n')
    print()

    dt64 = np.datetime64( "2011-11-11" )
    print('dt64:', dt64_to_float(dt64))
输出

df:
        date  number   date_float
0 1970-01-01       0  1970.000000
1 2014-01-01       1  2014.000000
2 2020-12-31       2  2020.997268
3 2019-12-31       3  2019.997260
4 2010-04-28       4  2010.320548

dt64: 2011.8602739726027

谢谢你的参考,尽管我还没能把它应用到我的具体问题上。当然,有一个解决方案是非音速的,像是非音阶的,它的形式是:datecol=london['date'];londates=[];对于datecol中的x:londates.append(float(x.replace('-','')),然后在londates数组中回归指定的伦敦数据。我目前收到了这个错误(我相信这是因为你在“date_delta”上的第三行):result[mask]=op(x[mask],y)TypeError:不支持的操作数类型-:“str”和“str”现在,如果我删除这个“date_delta”设置,那么它会编译,但问题是len(result.params)=唯一日期的长度,而不是一个线性回归性能的参数数。欢迎评论。如果有用的话:>>pd.version嗯,这很有趣。我有和你一样的熊猫。听起来您的
df['date']
列仍然是
str
类型。第二行
df['date']=pd.to_datetime(df['date'])
应负责将STR转换为日期对象。可能是因为输入csv中的奇怪字符而失败。我注意到您粘贴了一些值,它们看起来像“\xef\xbb\xbf2014-04-28”,在我看来,它们看起来像是存在一些垃圾字符(可能来自不完善的UTF-8转换)。我建议对输入进行清理,然后再进行一次尝试。事实上,问题在于日期条目的间距很奇怪,例如“20140428”而不是“20140428”。前者返回为“\xef\xbb\xbf20140428”,我不能直接将其转换为float,Pandas似乎也不能(这很奇怪?)。有没有UTF-8技巧让熊猫帮我清理这些条目?我将尝试一些特别的清理,并将很快返回我的特别解决方案s=''.join(如果j.isdigit(),则j代表x中的j),迭代日期条目x,然后是float(s)。这和你的评论让我找到了一个有效的解决方案。我仍然对处理这种浮点转换的更优雅的方法感兴趣。再次感谢