如何将时区感知日期时间读作pandas中带有read_csv的时区天真本地DatetimeIndex?

时间:2016-07-22 16:27:49

标签: python datetime pandas

当我使用pandas read_csv读取具有时区感知日期时间的列(并将此列指定为索引)时,pandas会将其转换为 timezone naive utc DatetimeIndex。

Test.csv中的数据:

DateTime,Temperature 2016-07-01T11:05:07+02:00,21.125 2016-07-01T11:05:09+02:00,21.138 2016-07-01T11:05:10+02:00,21.156 2016-07-01T11:05:11+02:00,21.179 2016-07-01T11:05:12+02:00,21.198 2016-07-01T11:05:13+02:00,21.206 2016-07-01T11:05:14+02:00,21.225 2016-07-01T11:05:15+02:00,21.233

从csv读取的代码:

In [1]: import pandas as pd

In [2]: df = pd.read_csv('Test.csv', index_col=0, parse_dates=True)

这会产生一个代表时区天真时间的索引:

In [3]: df.index

Out[3]: DatetimeIndex(['2016-07-01 09:05:07', '2016-07-01 09:05:09',
           '2016-07-01 09:05:10', '2016-07-01 09:05:11',
           '2016-07-01 09:05:12', '2016-07-01 09:05:13',
           '2016-07-01 09:05:14', '2016-07-01 09:05:15'],
          dtype='datetime64[ns]', name='DateTime', freq=None)

我尝试使用date_parser函数:

In [4]: date_parser = lambda x: pd.to_datetime(x).tz_localize(None)

In [5]: df = pd.read_csv('Test.csv', index_col=0, parse_dates=True, date_parser=date_parser)

这给出了相同的结果。

如何让read_csv创建一个时区初始的DatetimeIndex并代表本地时间而不是 utc time

我使用pandas 0.18.1。

4 个答案:

答案 0 :(得分:2)

根据the docs,默认date_parser使用dateutil.parser.parser。根据{{​​3}},默认是忽略时区。因此,如果您提供dateutil.parser.parser作为date_parser kwarg,则不会转换时区。

import dateutil

df = pd.read_csv('Test.csv', index_col=0, parse_dates=True, date_parser=dateutil.parser.parse)

print(df)

输出

                           Temperature
DateTime                              
2016-07-01 11:05:07+02:00       21.125
2016-07-01 11:05:09+02:00       21.138
2016-07-01 11:05:10+02:00       21.156
2016-07-01 11:05:11+02:00       21.179
2016-07-01 11:05:12+02:00       21.198
2016-07-01 11:05:13+02:00       21.206
2016-07-01 11:05:14+02:00       21.225
2016-07-01 11:05:15+02:00       21.233

答案 1 :(得分:2)

Alex的answer会导致时区感知DatetimeIndex。要获得OP提出的时区天真本地 DatetimeIndex,请通过设置dateutil.parser.parser告知ignoretz=True忽略时区信息:

import dateutil

date_parser = lambda x: dateutil.parser.parse(x, ignoretz=True)
df = pd.read_csv('Test.csv', index_col=0, parse_dates=True, date_parser=date_parser)

print(df)

输出

                     Temperature
DateTime                        
2016-07-01 11:05:07       21.125
2016-07-01 11:05:09       21.138
2016-07-01 11:05:10       21.156
2016-07-01 11:05:11       21.179
2016-07-01 11:05:12       21.198
2016-07-01 11:05:13       21.206
2016-07-01 11:05:14       21.225
2016-07-01 11:05:15       21.233

答案 2 :(得分:0)

我今天早些时候采用了dateutil技术,但后来改用了更快的替代方法:

date_parser = lambda ts: pd.to_datetime([s[:-5] for s in ts]))
  

编辑:s[:-5]是正确的(屏幕截图有错误)

在下面的屏幕截图中,我导入~55MB的制表符分隔文件。 dateutil方法有效,但需要更长的数量级。

enter image description here

这是使用pandas 0.18.1和dateutil 2.5.3。

编辑即使缺少Z-0000后缀,这个lambda函数也能正常工作......

date_parser = lambda ts: pd.to_datetime([s[:-5] if 'Z' in s else s for s in ts])

答案 3 :(得分:-1)

您甚至可以尝试:

date_parser = lambda x : pd.to_datetime(x.str[:-6])