【问题标题】:Concatenating Pandas datetime连接 Pandas 日期时间
【发布时间】:2014-09-18 15:30:17
【问题描述】:

我有这个问题的解决方案,实际上有 2 个解决方案,但我对它们不满意。原因是我试图读取的文件有大约 1200 万行,并且使用这些解决方案需要花费大量时间来处理它们。主要是解决方案是逐行操作。

所以,我是这样读取文件的:

In  [1]: df = pd.read_csv('C:/Projects/NPMRDS/FHWA_TASK2-4_NJ_09_2013_TT.CSV')
         df.head()

Out [1]:     TMC        DATE    EPOCH   Travel_TIME_ALL_VEHICLES    Travel_TIME_PASSENGER_VEHICLES  Travel_TIME_FREIGHT_TRUCKS
         0   103N04152  9252013 211     12                          12                              NaN
         1   103N04152  9262013 0       7                           7                               NaN
         2   103N04152  9032013 177     8                           8                               NaN
         3   103N04152  9042013 176     8                           9                               7

我的问题在于 DATEEPOCH 列。我想将它们合并到一个日期时间列中。

  • DATE 采用“%m%d%Y”格式(缺少前导零)
  • EPOCH 是一天的 5 分钟纪元:

    Time        EPOCH
    00:00:00 => 0
    00:05:00 => 1
    ...
    ...
    12:00:00 => 144
    12:05:00 => 145
    ...
    ...
    23:50:00 => 286
    23:55:00 => 287
    

我想要的是这样的:

In  [2]: df.head()

Out [2]:     TMC        DATE_TIME           DATE    EPOCH   Travel_TIME_ALL_VEHICLES    Travel_TIME_PASSENGER_VEHICLES  Travel_TIME_FREIGHT_TRUCKS
         0   103N04152  2013-09-25 17:35:00 9252013 211     12                          12                              NaN
         1   103N04152  2013-09-26 00:00:00 9262013 0       7                           7                               NaN
         2   103N04152  2013-09-03 14:45:00 9032013 177     8                           8                               NaN
         3   103N04152  2013-09-04 14:30:00 9042013 176     8                           9                               7

现在,我可以通过执行以下三件事中的任何一项来逐行执行此操作:

In  [3]: df = pd.read_csv('C:/Projects/NPMRDS/FHWA_TASK2-4_NJ_09_2013_TT.CSV',
                 converters={'DATE': lambda x: datetime.datetime.strptime(x, '%m%d%Y'),
                             'EPOCH': lambda x: str(datetime.timedelta(minutes = int(x)*5))},
                 parse_dates = {'date_time': ['DATE', 'EPOCH']},
                 keep_date_col = True)
         df.head()

Out [3]:    date_time           TMC         DATE        EPOCH       Travel_TIME_ALL_VEHICLES    Travel_TIME_PASSENGER_VEHICLES  Travel_TIME_FREIGHT_TRUCKS
         0  2013-09-25 17:35:00 103N04152   2013-09-25  17:35:00    12                          12                              NaN
         1  2013-09-26 00:00:00 103N04152   2013-09-26  00:00:00    7                           7                               NaN
         2  2013-09-03 14:45:00 103N04152   2013-09-03  14:45:00    8                           8                               NaN
         3  2013-09-04 14:40:00 103N04152   2013-09-04  14:40:00    8                           9                               7
         4  2013-09-05 09:35:00 103N04152   2013-09-05  09:35:00    10                          10                              NaN

在这种方法中,我丢失了 DATEEPOCH 的原始格式,但它并不会真正影响对数据帧的进一步计算。我可以使用 date_parser,而不是使用 converters 作为参数。或者,在读取数据后,类似于第 1 行,我可以这样做:

In  [4]: df = pd.read_csv('C:/Projects/NPMRDS/FHWA_TASK2-4_NJ_09_2013_TT.CSV')
         df['date_time'] = pd.to_datetime([datetime.datetime.strptime(str(df['DATE'][x]), '%m%d%Y') + datetime.timedelta(minutes = int(df['EPOCH'][x]*5)) for x in range(len(df))])
         df.head()

Out [4]:    TMC         DATE    EPOCH   Travel_TIME_ALL_VEHICLES    Travel_TIME_PASSENGER_VEHICLES  Travel_TIME_FREIGHT_TRUCKS  DATE_TIME
         0  103N04152   9252013 211     12                          12                              NaN                         2013-09-25 17:35:00
         1  103N04152   9262013 0       7                           7                               NaN                         2013-09-26 00:00:00
         2  103N04152   9032013 177     8                           8                               NaN                         2013-09-03 14:45:00
         3  103N04152   9042013 176     8                           9                               7                           2013-09-04 14:40:00
         4  103N04152   9052013 115     10                          10                              NaN                         2013-09-05 09:35:00

一个更理想的结果(不用担心列的顺序),但仍然是逐行的,并且需要大量的时间。

然后是pandas.to_datetimepandas.to_timedelta,运行速度比上面介绍的方法快很多。但是如果不求助于字符串函数,我就无法将结果合并在一起,这些函数又主要是逐行的。 有谁知道更好的方法吗?

编辑:解决方案!!!

除了chrisb's 回答之外,我也找到了一种方法。诀窍在于将pandas.to_datetime() 中的box 参数设置为False。像这样:

df['DATE_TIME'] = pd.to_datetime(df['DATE'], format='%m%d%Y', box=False) + pd.to_timedelta(df['EPOCH']*5*60, unit='s')

将其设置为 False 会返回一个 numpy.datetime[64] 数组,而不是 pandas.DatetimeIndex。更多信息可以在pandas.to_datetime() 文档中找到。而且,pandas.to_timedelta() 不适用于 unit='m'

【问题讨论】:

    标签: python datetime python-3.x pandas


    【解决方案1】:

    试试这个 - 在 4M 行测试数据上,我将运行时间减少到大约 1 秒(与 15 秒相比)。

    df = pd.read_csv('temp.csv')
    
    df['DATE'] = pd.to_datetime(df['DATE'], format='%m%d%Y')
    df['EPOCH'] = pd.to_timedelta((df['EPOCH'].astype(int) * 5).astype('timedelta64[m]'))
    df['DATE_TIME'] = df['DATE'] + df['EPOCH']
    

    【讨论】:

    • 我正在尝试支持您的答案,但我需要 15 个代表点才能做到这一点……您的答案完美无缺,但是,我在一行代码中找到了另一种类似的方法。它就像:df['DATE_TIME'] = pd.to_datetime(df['DATE'], format='%m%d%Y', box=False) + pd.to_timedelta(df['EPOCH']*5*60, unit='s')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    相关资源
    最近更新 更多