时间戳偏移(天、小时、分钟等)

1 投票
2 回答
756 浏览
提问于 2025-04-18 18:11

假设我在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

这是你的数据。

不过要注意,如果你的时区偏移不是整数,这些方法都会失败。

撰写回答