合并Pandas日期时间

3
我有两个解决方案来解决这个问题,但我对它们不太满意。原因是我尝试读取的文件大约有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 is in '%m%d%Y' format (with the leading zero missing)

  • EPOCH is 5 minute epoch of a day:

     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的原始格式,但这并不会真正影响数据帧上的进一步计算。除了使用converters作为参数外,我也可以使用date_parser。或者,在读取数据后,类似于第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_datetime` 和 `pandas.to_timedelta`,比上述方法运行得快得多。 但是,我无法将结果合并在一起,而不必使用字符串函数,这些函数主要仍然是逐行进行。 有没有人知道更好的方法?
2个回答

3

试试这个-对我来说,这个方法可将测试数据的运行时间从15秒缩短至1秒。

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') - Kartik

0

除了 chrisb 的回答,我还找到了另一种方法。技巧在于在 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'

这个答案是由OP Kartik 在CC BY-SA 3.0下发布的,作为编辑问题连接Pandas日期时间的回答。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接