pandasTimedelta和timedelta64[ns]的区别?

The difference between pandas Timedelta and timedelta64[ns]?

我想使用函数total_seconds。

我通过从结尾减去开头来获得两个日期之间的差异。

df["diff"] = (df["End"] - df["Start"])

产生:

0      0 days 00:12:08
1      0 days 00:18:56
2      0 days 00:17:17
3      0 days 00:48:46
4      0 days 00:21:02
             ...      
7015   0 days 00:14:32
7016   0 days 00:08:33
7017   0 days 00:19:38
7018   0 days 00:18:41
7019   0 days 00:37:35
Name: diff, Length: 7020, dtype: timedelta64[ns]

有一个函数total seconds。但它对我创建的 df["diff"] 不起作用。 timedelta64[ns] 有什么不同吗?

如果我在 df["diff"] 的单个元素上调用 pd.Timedelta() 而不是调用 total_seconds().

,则函数 total_seconds() 有效

我想在这里澄清一下 dtype 以及如何在整个系列中使用 total_seconds 函数。

您可以使用 Timedelta.total_seconds 方法来访问 Timedelta 的单个实例的总秒数,例如:

>>> df['diff'].iloc[0].total_seconds()
728.0

但是如果你想访问 Timedelta 个实例的列表(Series)的总秒数,你必须使用访问器 dt 因为列表是 TimedeltaIndexTimedelta 个实例的集合):

>>> df['diff'].dt.total_seconds()
0        728.0
1       1136.0
2       1037.0
3       2926.0
4       1262.0
7015     872.0
7016     513.0
7017    1178.0
7018    1121.0
7019    2255.0
Name: diff, dtype: float64

假设你的例子:

data = {'diff': ['0 days 00:12:08', '0 days 00:18:56', '0 days 00:17:17']}
df = pd.DataFrame(data)

您可以转换每个值:

>>> df['diff'].apply(pd.Timedelta)
0   0 days 00:12:08
1   0 days 00:18:56
2   0 days 00:17:17
Name: diff, dtype: timedelta64[ns]

# OR

>>> [pd.Timedelta(x) for x in df['diff']]
[Timedelta('0 days 00:12:08'),
 Timedelta('0 days 00:18:56'),
 Timedelta('0 days 00:17:17')]

或者您可以转换整个列表:

>>> pd.to_timedelta(df['diff'])
0   0 days 00:12:08
1   0 days 00:18:56
2   0 days 00:17:17
Name: diff, dtype: timedelta64[ns]

# OR

>>> pd.TimedeltaIndex(df['diff'])
TimedeltaIndex(['0 days 00:12:08', '0 days 00:18:56', '0 days 00:17:17'],
               dtype='timedelta64[ns]', name='diff', freq=None)

离你不远了。请参阅下面的代码:

df["diff"] = (df["End"] - df["Start"]).astype('timedelta64[s]')

在行动

df = pd.DataFrame({'begin' : ['08:00', '10:00', '14:00'], 
                   'end'   : ['14:00', '17:00', '22:00']})

解决方案;秒

df['diff_hours']=(pd.to_datetime(df['end'], format="%H:%M")-pd.to_datetime(df['begin'], format="%H:%M")).astype('timedelta64[s]')

解答分钟数

df['diff_hours']=(pd.to_datetime(df['end'], format="%H:%M")-pd.to_datetime(df['begin'], format="%H:%M")).astype('timedelta64[s]')/60

df['diff_hours']=(pd.to_datetime(df['end'], format="%H:%M")-pd.to_datetime(df['begin'], format="%H:%M")).astype('timedelta64[m]')

Pandas已经明确记载了Timedelta limitations。我是这样理解的;

DataFrame/Series 减去日期时间的操作 return 构造 timedelta[ns] 系列作为本机 timedelta 分辨率。因此,您不能在转换为日期时间频率时应用 .astype('timedelta64[ns]')。它 return 本身。这解释了为什么如果您尝试 .astype('timedelta64[ns]')

最终会得到 0 days 00:12:08

要转换为其他频率,您必须除以数字 timedelta 或 astype 为特定的 timedelta,当然不能是 timedelta64[ns] 本身。

你知道,df['diff_hours']=(pd.to_datetime(df['end'], format="%H:%M")-pd.to_datetime(df['begin'], format="%H:%M")).dt.total_seconds() 有效。因为正如 python documentation 中所解释的那样,在这种情况下,它是特定的 [timedelta type][2](请参见下图了解 timedelta 类型),在这种情况下,timedelta 系列中的总秒数。

您只知道 .astype('timedelta64[ns]')0 days 00:12:08 格式保留任何日期时间替换的结果。即使是皮秒 (.astype('timedelta64[ps]')) 也比纳秒少得多