使用pandas高效地读取/移出超出范围的日期时间

时间:2016-09-12 12:26:33

标签: python datetime pandas

所以我有一个数据集(一堆csv文件),它包含以下形式的(匿名)日期时间:

  

3202-11-11 14:51:00 EST

每个实体的日期已经移动了一些随机时间。因此,给定实体的时间差异仍然有意义。

尝试使用例如转换时 pd.to_datetime(['3202-11-11 14:51:00 EST'], format='%Y-%m-%d %H:%M:%S EST'),这将导致“OutOfBoundsDatetime”错误。

对于我的用例,理想的是指定在读取csv文件时转移所有日期的年数,s.t。它们在有效的pandas日期时间范围内。

您是否知道如何有效地解决这个问题?我必须在~40k实体/ csv文件上执行此操作,每个csv有10到10k个这样的日期。 (我的非效率想法:通过python datetime,它可以工作多年,直到9999,在那里转换日期,然后转换为pandas datetime)

编辑:我也在IRC #pydata中提出了这个问题并得到了这个答案(谢谢jboy):

>>> from datetime import timedelta
>>> offset = timedelta(days=10000)
>>> df
                  time
0  3001-01-01 01:00:01
1  3001-01-01 01:00:02
2  3001-01-01 01:00:05
3  3001-01-01 01:00:09

>>> df['time'].map(lambda t: t - offset)
0    2973-08-15 01:00:01
1    2973-08-15 01:00:02
2    2973-08-15 01:00:05
3    2973-08-15 01:00:09
Name: time, dtype: object

我唯一要做的就是:

 df['time'].map(lambda t: datetime.datetime.strptime(t, '%Y-%m-%d %H:%M:%S EST')-offset)

因为我的时间栏仍然是str而不是datetime.datetime。

2 个答案:

答案 0 :(得分:0)

你可以做的一件事就是在字符串级别处理这个问题,扣除一些年份(在下面,1200):

s = '3202-11-11 14:51:00 EST'

>>> In [21]: pd.to_datetime(str(int(s[: 4]) - 1200) + s[4: ])
Out[21]: Timestamp('2002-11-11 14:51:00')

您也可以对此进行矢量化。假设你从

开始
dates = pd.Series([s, s])

然后你可以使用

>>> pd.to_datetime((dates.str[: 4].astype(int) - 1200).astype(str) + dates.str[4: ])
0   2002-11-11 14:51:00
1   2002-11-11 14:51:00
dtype: datetime64[ns]

答案 1 :(得分:0)

pandas datetime对象使用64位整数来表示时间,由于它具有纳秒级分辨率,因此上限位于2262-04-11,引用为here

我不确定你是否计划对时间对象进行任何时间操作,但如果你只是想在数据框中表示它们,我就不明白为什么不使用python datetime对象只是按原样表示它们而不做任何时间转换:

示例

from datetime import datetime
s = pd.Series(['3202-11-11 14:51:00 EST', '9999-12-31 12:21:00 EST'])
s = s.apply(lambda x: datetime.strptime(x[:-4], "%Y-%m-%d %H:%M:%S"))

<强>返回

0    3202-11-11 14:51:00
1    9999-12-31 12:21:00
dtype: object

在第一个单元格上运行快速嗅探类型检查:

>>> type(s[0])
<type 'datetime.datetime'>