时间戳偏移(天、小时、分钟等)
假设我在Pandas中有一个时间戳:
Timestamp('2014-08-07 11:01:02')
我想知道这个时间戳在这一小时内有多少毫秒。怎么在Pandas中做到这一点呢?
在上面的例子中,我想计算以下两个时间戳之间的毫秒差:
Timestamp('2014-08-07 11:01:02')
Timestamp('2014-08-07 11:00:00')
如果我有一个包含时间戳的序列,像下面这样,我该怎么做呢?
timestamp
1071 2014-08-07 11:01:02
3291 2014-08-07 11:01:00
3355 2014-08-07 05:01:00
3518 2014-08-07 05:01:03
4207 2014-08-07 13:01:03
5039 2014-08-07 18:01:04
5063 2014-08-07 23:01:03
6926 2014-08-07 06:01:02
6965 2014-08-07 06:01:02
7107 2014-08-07 05:01:01
Name: events_source_timestamp, dtype: datetime64[ns]
更新:
尝试了@Jeff的回答。以下代码可以正常工作:
In [210]: temp_df = m*(df.astype('i8')/m).astype('i8')
Out[210]:
A_timestamp B_timestamp
1 1407405600000000000 1407405600000000000
2 1407445200000000000 1407445200000000000
3 1407434400000000000 1407434400000000000
4 1407445200000000000 1407445200000000000
5 1407438000000000000 1407438000000000000
6 1407402000000000000 1407402000000000000
7 1407420000000000000 1407420000000000000
8 1407438000000000000 1407438000000000000
9 1407438000000000000 1407438000000000000
10 1407420000000000000 1407420000000000000
11 1407420000000000000 1407420000000000000
12 1407441600000000000 1407441600000000000
13 1407409200000000000 1407409200000000000
14 1407391200000000000 1407391200000000000
15 1407409200000000000 1407409200000000000
16 1407420000000000000 1407420000000000000
但是接下来
pd.DatetimeIndex(temp_df)
却出现了错误:
/Users/josh/anaconda/envs/py3k/lib/python3.3/site-packages/pandas/tseries/tools.py in parse_time_string(arg, freq, dayfirst, yearfirst)
472 except Exception as e:
473 # TODO: allow raise of errors within instead
--> 474 raise DateParseError(e)
475
476 if parsed is None:
DateParseError: unknown string format
2 个回答
3
这里有一些标准的方法来处理这个问题,具体的操作可以参考文档,点击这里查看关于时间差的处理方法。
In [16]: s = Series([Timestamp('20140804 11:01:12'),Timestamp('20140804 11:00:00')])
In [17]: s
Out[17]:
0 2014-08-04 11:01:12
1 2014-08-04 11:00:00
dtype: datetime64[ns]
In [18]: (s-Timestamp('20140804 11:00:00')).astype('timedelta64[ms]')
Out[18]:
0 72000
1 0
dtype: float64
In [19]: (s-Timestamp('20140804 11:00:00')) / np.timedelta64(1,'ms')
Out[19]:
0 72000
1 0
dtype: float64
这里有一种方法可以把时间序列四舍五入到最近的小时,虽然现在这个方法有点不太完美,应该作为一个正式的DatetimeIndex方法来实现,更多信息可以查看这里。
In [169]: m = int(1e9*60*60)
In [170]: rounded = Series(pd.DatetimeIndex(m*(s.astype('i8')/m).astype('i8')))
In [171]: rounded
Out[171]:
0 2014-08-04 11:00:00
1 2014-08-04 11:00:00
dtype: datetime64[ns]
In [172]: (s-rounded).astype('timedelta64[ms]')
Out[172]:
0 72000
1 0
dtype: float64
1
如果你的 index
是一个 DatetimeIndex
,你可以这样做:
hour_as_integer = int(np.timedelta64(1, 'h') / np.timedelta64(1, 'ns'))
ms_as_integer = int(np.timedelta64(1, 'ms') / np.timedelta64(1, 'ns'))
ts.asi8 % hour_as_integer // ms_as_integer
这里的 asi8
是一个属性,它把索引转换成内部表示,也就是64位的微秒级Unix时间戳整数。然后,我们用这个数字去除以 10 ** 6 * 3600
(这是一个小时的微秒数),得到的余数再除以 10 ** 3
,就能得到毫秒数。
如果你有一个单独的 pd.Timestamp
对象,可以使用:
ts.asm8.astype("int64") % hour_as_integer // ms_as_integer
如果你有一个 Series
,可以这样做:
series.astype("int64") % hour_as_integer // ms_as_integer
用最后一个方法,我得到了:
1071 62000 3291 60000 3355 60000 3518 63000 4207 63000 5039 64000 5063 63000 6926 62000 6965 62000 7107 61000 Name: events_source_timestamp, dtype: int64
这是你的数据。
不过要注意,如果你的时区偏移不是整数,这些方法都会失败。