如何在python中仅使用datetime的时间部分?

如何在python中仅使用datetime的时间部分?,python,pandas,Python,Pandas,我使用了一些日期和时间变量,但我只想使用时间部分 例如,当我执行“数据类型”操作时,某列a和B都显示“数据类型('O')”,但a的输出是: 0 2017-11-29 17:14:00 1 2017-02-15 15:35:00 2 2018-10-18 08:02:00 3 2017-06-22 09:25:00 而对于B,则是: 0 2017-11-29 20:00:00 1 2017-02-15 16:43

我使用了一些日期和时间变量,但我只想使用时间部分

例如,当我执行“数据类型”操作时,某列a和B都显示“数据类型('O')”,但a的输出是:

0        2017-11-29 17:14:00
1        2017-02-15 15:35:00
2        2018-10-18 08:02:00
3        2017-06-22 09:25:00
而对于B,则是:

0        2017-11-29 20:00:00
1        2017-02-15 16:43:00
2        2018-10-18 11:08:00
3        2017-06-22 11:29:00
然后我会这样做:

import datetime
from datetime import datetime
df = df[df['A'].apply(lambda v: isinstance(v, datetime))] 
df = df[df['B'].apply(lambda v: isinstance(v, datetime))] 
然而,我想做的是减去A和B的时间。只有时间,而不是日期


例如,当我执行df['A']-df['B']时,我只希望第一行的输出是02:46。另外,如何将其转换为分钟,但作为整数?

如果这是数据帧的形状:

                    A                   B
0 2017-11-29 17:14:00 2017-11-29 20:00:00
1 2017-02-15 15:35:00 2017-02-15 16:43:00
2 2018-10-18 08:02:00 2018-10-18 11:08:00
3 2017-06-22 09:25:00 2017-06-22 11:29:00
然后,您需要做的就是创建一个datetime对象,然后对其应用您的操作

df[['A','B']] = df[['A','B']].apply(pd.to_datetime)

df['B'] - df['A']

0   02:46:00
1   01:08:00
2   03:06:00
3   02:04:00
dtype: timedelta64[ns]
另一种方法是使用
pd.to_timedelta
np.timedelta64
假设两列都已经是日期时间

   df['diff'] = abs(
    pd.to_timedelta(df["A"].dt.time.astype(str), "h")
    - pd.to_timedelta(df["B"].dt.time.astype(str), "h")
) / np.timedelta64(1, "h")


如果这是数据帧的形状:

                    A                   B
0 2017-11-29 17:14:00 2017-11-29 20:00:00
1 2017-02-15 15:35:00 2017-02-15 16:43:00
2 2018-10-18 08:02:00 2018-10-18 11:08:00
3 2017-06-22 09:25:00 2017-06-22 11:29:00
然后,您需要做的就是创建一个datetime对象,然后对其应用您的操作

df[['A','B']] = df[['A','B']].apply(pd.to_datetime)

df['B'] - df['A']

0   02:46:00
1   01:08:00
2   03:06:00
3   02:04:00
dtype: timedelta64[ns]
另一种方法是使用
pd.to_timedelta
np.timedelta64
假设两列都已经是日期时间

   df['diff'] = abs(
    pd.to_timedelta(df["A"].dt.time.astype(str), "h")
    - pd.to_timedelta(df["B"].dt.time.astype(str), "h")
) / np.timedelta64(1, "h")


一种解决方法是将日期减去每个日期时间,以确保只比较时间,然后减去:

(df.A - df.A.dt.floor('d')) - (df.B - df.B.dt.floor('d'))

0   -1 days +21:14:00
1   -1 days +22:52:00
2   -1 days +20:54:00
3   -1 days +21:56:00
dtype: timedelta64[ns]

一种解决方法是将日期减去每个日期时间,以确保只比较时间,然后减去:

(df.A - df.A.dt.floor('d')) - (df.B - df.B.dt.floor('d'))

0   -1 days +21:14:00
1   -1 days +22:52:00
2   -1 days +20:54:00
3   -1 days +21:56:00
dtype: timedelta64[ns]
减去A和B的时间。只减去时间,不减去日期

减去午夜后的秒数

>>> a1 = (a.dt.hour * 3600) + (a.dt.minute * 60) + (a.dt.microsecond / 1000000)
>>> b1 = (b.dt.hour * 3600) + (b.dt.minute * 60) + (b.dt.microsecond / 1000000)
>>> b1-a1
0     9960.0
1     4080.0
2    11160.0
3     7440.0
dtype: float64
转换为
timedelta

>>> pd.to_timedelta(b1-a1, unit='S')
0   02:46:00
1   01:08:00
2   03:06:00
3   02:04:00
dtype: timedelta64[ns]
>>> 


减去A和B的时间。只减去时间,不减去日期

减去午夜后的秒数

>>> a1 = (a.dt.hour * 3600) + (a.dt.minute * 60) + (a.dt.microsecond / 1000000)
>>> b1 = (b.dt.hour * 3600) + (b.dt.minute * 60) + (b.dt.microsecond / 1000000)
>>> b1-a1
0     9960.0
1     4080.0
2    11160.0
3     7440.0
dtype: float64
转换为
timedelta

>>> pd.to_timedelta(b1-a1, unit='S')
0   02:46:00
1   01:08:00
2   03:06:00
3   02:04:00
dtype: timedelta64[ns]
>>> 


您可以这样做:

pd.to_timedelta(df[['A', 'B']].astype('datetime64').diff(axis=1)['B'].dt.seconds * 10 ** 9)

# 0   02:46:00
# 1   01:08:00
# 2   03:06:00
# 3   02:04:00
# Name: B, dtype: timedelta64[ns]
这将提取
timedelta
对象的
seconds
部分,并在分解
纳秒后将其转换回
timedelta

或者,如果您只关心几秒钟:

pd.to_timedelta(df[['A', 'B']].astype('datetime64').diff(axis=1)['B'].dt.seconds, 's')
为了解释,所采取的步骤是:

  • 处理
    dtype('O')
    并转换为
    datetime64
    对象
  • 根据轴=1计算
    A
    B
    的差值
  • 从结果列
    B
  • 提取
    timedelta
    seconds
    (删除任何天数、月份等)
  • seconds
    转换回
    timedelta
    对象
  • 您可以这样做:

    pd.to_timedelta(df[['A', 'B']].astype('datetime64').diff(axis=1)['B'].dt.seconds * 10 ** 9)
    
    # 0   02:46:00
    # 1   01:08:00
    # 2   03:06:00
    # 3   02:04:00
    # Name: B, dtype: timedelta64[ns]
    
    这将提取
    timedelta
    对象的
    seconds
    部分,并在分解
    纳秒后将其转换回
    timedelta

    或者,如果您只关心几秒钟:

    pd.to_timedelta(df[['A', 'B']].astype('datetime64').diff(axis=1)['B'].dt.seconds, 's')
    
    为了解释,所采取的步骤是:

  • 处理
    dtype('O')
    并转换为
    datetime64
    对象
  • 根据轴=1计算
    A
    B
    的差值
  • 从结果列
    B
  • 提取
    timedelta
    seconds
    (删除任何天数、月份等)
  • seconds
    转换回
    timedelta
    对象

  • 这回答了你的问题吗?您是否尝试过使用
    .time()
    方法从
    datetime
    中获取
    time
    ,然后减去它们?这是否回答了您的问题?您是否尝试过使用
    .time()
    方法从
    datetime
    中获取
    time
    ,然后减去它们?这是很棘手的,因为在您的示例中
    B>A
    ,但是尝试
    A-B
    会得到错误的输出。而且,OP只想减去时间。如果日期不同,您的答案也会减去日期。您是对的,让我编辑@Erfan r.ookThank!成功了。我只是有点好奇。如果您处理的是数字,即“timedelta/datetime”,那么为什么在处理astype(str)时它会起作用?为什么字符串?@bonaqua在幕后日期时间只是一个数字,
    to_datetime
    to_timedelta
    通过将日期和时间的字符串表示形式转换为数字来工作,因为我们只需要数据的时间元素,我们提取它,确保它是字符串而不是datetime对象,并将其转换为时间增量。然后,我们根据您的要求执行数学运算。这很棘手,因为在您的示例中,
    B>A
    ,但尝试
    A-B
    ,会得到错误的输出。此外,OP只想减去时间。如果日期不同,您的答案也会减去日期。您是对的,让我编辑@Erfan r.ookThank!成功了。我只是有点好奇。如果您处理的是数字,即“timedelta/datetime”,那么为什么在处理astype(str)时它会起作用?为什么字符串?@bonaqua在幕后日期时间只是一个数字,
    to_datetime
    to_timedelta
    通过将日期和时间的字符串表示形式转换为数字来工作,因为我们只需要数据的时间元素,我们提取它,确保它是字符串而不是datetime对象,并将其转换为时间增量。然后,我们根据您的要求执行数学运算。