Pandas 中有符号时间增量为有符号秒数

Signed time deltas to signed seconds in Pandas

考虑以下系列:

> df['time_delta']

0   -1 days +00:08:11
1     0 days 01:57:46
2     0 days 00:58:34
3     0 days 17:30:23
4   -1 days +21:44:34
5   -2 days +22:01:56
6     0 days 03:18:57
7   -1 days +21:44:48
8   -1 days +00:07:56
Name: time_delta, dtype: timedelta64[ns]

假设我想将此时间增量转换为 有符号 秒。即:

例如:

我怎样才能获得这种转化?


尝试失败

当我尝试往常时:

temp_df['seconds'] = temp_df['time_delta'].dt.seconds

我最终得到:

         time_delta  seconds
0 -1 days +00:08:11      491
1   0 days 01:57:46     7066
2   0 days 00:58:34     3514
3   0 days 17:30:23    63023
4 -1 days +21:44:34    78274
5 -2 days +22:01:56    79316
6   0 days 03:18:57    11937
7 -1 days +21:44:48    78288
8 -1 days +00:07:56      476

正确处理了增量,但没有负增量。要看到这一点,请注意负增量似乎忽略了日偏移量的 符号。即在上面的例子中:


只需在 dt.total_seconds 之前调用 abs 以获得绝对值:

df['seconds'] = df['time_delta'].abs().dt.total_seconds()

示例:

In [63]:
df = pd.DataFrame({'date_time':pd.date_range(dt.datetime(2015,1,1,12,10,32), dt.datetime(2015,1,3,12,12,30,2))})
df['time_delta'] = df['date_time'] - dt.datetime(2015,1,2)
df

Out[63]:
            date_time        time_delta
0 2015-01-01 12:10:32 -1 days +12:10:32
1 2015-01-02 12:10:32   0 days 12:10:32
2 2015-01-03 12:10:32   1 days 12:10:32

In [64]:    
df['time_delta'].abs().dt.total_seconds()

Out[64]:
0     42568
1     43832
2    130232
Name: time_delta, dtype: float64

要添加符号,您可以与 pd.Timedelta(0):

进行比较
In [78]:
df['seconds'] = df['time_delta'].abs().dt.total_seconds()
df.loc[df['time_delta'] < pd.Timedelta(0), 'seconds'] = -df['seconds']
df

Out[78]:
            date_time        time_delta  seconds
0 2015-01-01 12:10:32 -1 days +12:10:32   -42568
1 2015-01-02 12:10:32   0 days 12:10:32    43832
2 2015-01-03 12:10:32   1 days 12:10:32   130232

不过,我觉得@Ami Tamory 的回答更好

编辑 在睡觉之后我意识到这只是 dt.total_seconds:

In [137]:
df['time_delta'].dt.total_seconds()

Out[137]:
0    -42568
1     43832
2    130232
Name: time_delta, dtype: float64

如果它是一个 Timedelta 对象,只需将它除以 Timedelta(seconds=1):

>>> pd.Timedelta(days=-1) / pd.Timedelta(seconds=1)
-86400.0