我有两个解决方案来解决这个问题,但我对它们不太满意。原因是我尝试读取的文件大约有1200万行,使用这些解决方案处理它们需要大量时间。主要原因是这些解决方案是逐行操作。
所以,我是这样读取文件的:
现在,我可以像我之前提到的那样逐行进行操作,方法有以下三种:
更理想的结果(不必担心列顺序),但仍然逐行进行,需要大量时间。 然后,有 `pandas.to_datetime` 和 `pandas.to_timedelta`,比上述方法运行得快得多。 但是,我无法将结果合并在一起,而不必使用字符串函数,这些函数主要仍然是逐行进行。 有没有人知道更好的方法?
所以,我是这样读取文件的:
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
我的问题出在 DATE 和 EPOCH 列上,我想将它们合并成一个日期时间列。
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
在这种方法中,我失去了DATE和EPOCH的原始格式,但这并不会真正影响数据帧上的进一步计算。除了使用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`,比上述方法运行得快得多。 但是,我无法将结果合并在一起,而不必使用字符串函数,这些函数主要仍然是逐行进行。 有没有人知道更好的方法?
df['DATE_TIME'] = pd.to_datetime(df['DATE'], format='%m%d%Y', box=False) + pd.to_timedelta(df['EPOCH']*5*60, unit='s')
- Kartik