Python pandas中两个datetime.time列之间的微秒差异?

5

我有一个Python pandas数据框,其中包含两列:time1time2:

     time1             time2
13:00:07.294234    13:00:07.294234 
14:00:07.294234    14:00:07.394234 
15:00:07.294234    15:00:07.494234 
16:00:07.294234    16:00:07.694234 

我该如何生成一个第三列,其中包含time1time2之间的微秒差异,如果可能的话,以整数形式呈现?
4个回答

5

如果你在这些日期前面添加一个实际的日期,那么就可以将它们转换为datetime64列:

In [11]: '2014-03-19 ' + df
Out[11]: 
                        time1                       time2
0  2014-03-19 13:00:07.294234  2014-03-19 13:00:07.294234
1  2014-03-19 14:00:07.294234  2014-03-19 14:00:07.394234
2  2014-03-19 15:00:07.294234  2014-03-19 15:00:07.494234
3  2014-03-19 16:00:07.294234  2014-03-19 16:00:07.694234

[4 rows x 2 columns]

In [12]: df = ('2014-03-19 ' + df).astype('datetime64[ns]')
Out[12]: 
                       time1                      time2
0 2014-03-19 20:00:07.294234 2014-03-19 20:00:07.294234
1 2014-03-19 21:00:07.294234 2014-03-19 21:00:07.394234
2 2014-03-19 22:00:07.294234 2014-03-19 22:00:07.494234
3 2014-03-19 23:00:07.294234 2014-03-19 23:00:07.694234

现在你可以减去这些列:
In [13]: delta = df['time2'] - df['time1']

In [14]: delta
Out[14]: 
0          00:00:00
1   00:00:00.100000
2   00:00:00.200000
3   00:00:00.400000
dtype: timedelta64[ns]

要获得微秒数,只需将基础纳秒数除以1000:

In [15]: t.astype(np.int64) / 10**3
Out[15]: 
0         0
1    100000
2    200000
3    400000
dtype: int64

正如Jeff所指出的,在最近版本的numpy中,你可以用1微秒进行除法:

In [16]: t / np.timedelta64(1,'us')
Out[16]: 
0         0
1    100000
2    200000
3    400000
dtype: float64

3
可以通过“np.timedelta64(1,'us')”进行除法运算。 - Jeff

0

最简单的方法就是这样:

(pd.to_datetime(df['time2']) - pd.to_datetime(df['time1'])) / np.timedelta64(1, 'us')'


这个解决方案给了我一个 TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time' 的错误。 - firelynx

0
起初我认为由于没有绿色勾号,这里没有正确答案。但正如Jeff在评论中指出的那样,我错了。
无论如何,这是我的贡献。
首先,显而易见的是将datetime.time转换为timedelta
df['delta'] = (pd.to_timedelta(df.time2.astype(str)) - pd.to_timedelta(df.time1.astype(str)))

             time1            time2           delta
0  13:00:07.294234  13:00:07.294234        00:00:00
1  14:00:07.294234  14:00:07.394234 00:00:00.100000
2  15:00:07.294234  15:00:07.494234 00:00:00.200000
3  16:00:07.294234  16:00:07.694234 00:00:00.400000

现在我们有了timedelta,我们可以将其除以一微秒,以获取微秒数。
df['microsecond_delta'] = df.delta / pd.np.timedelta64(1, 'us')

             time1            time2           delta  microsecond_delta
0  13:00:07.294234  13:00:07.294234        00:00:00                  0
1  14:00:07.294234  14:00:07.394234 00:00:00.100000             100000
2  15:00:07.294234  15:00:07.494234 00:00:00.200000             200000
3  16:00:07.294234  16:00:07.694234 00:00:00.400000             400000

我必须补充说明,这非常反直觉,但似乎这是唯一的方法。似乎没有直接访问毫秒的方法。我尝试通过应用lambda函数来实现:

df.delta.apply(lambda x: x.microseconds)
AttributeError: 'numpy.timedelta64' object has no attribute 'microseconds'

对于纳秒毫秒等等,同样适用。


下面@acushner的答案是正确的(虽然没有输出)。顺便提一下,使用“ .map”方法的答案非常低效。 - Jeff
@Jeff 我没有看到那个答案。该死,所有的研究都白费了。 - firelynx
@Jeff 当我尝试使用acushners的解决方案时,实际上会出现“不支持的操作数类型:'datetime.time和'datetime.time'”的错误。 - firelynx
如果您有实际的字符串,则可以使用pd.to_datetime(df.col.astype(str))这个惯用语句(datetime.time是一个奇怪的东西,转换为Timedelta尚未实现)。建议使用此方法而不是使用.map - Jeff
@Jeff 这个问题指定了 datetime.time 对象存在于列中。这是我尝试过的。我已经改变了我的答案来使用 astype - firelynx
通常进行频率转换的方法是通过除法或使用“.astype('timedelta64[us]')”(它们具有略微不同的舍入约定),请参阅文档此处 - Jeff

-1
使用dateutil库,您可以将时间戳列转换为“真实”的时间戳:
df.time1 = df.time1.apply(dateutil.parser.parse) df.time2 = df.time2.apply(dateutil.parser.parse)
之后您想要定义一个新列,如下所示:
df['delta'] = df.time2 - df.time1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接