当我使用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。
答案 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
方法有效,但需要更长的数量级。
这是使用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])