在 python 中将 timedelta 与 dt.time 进行比较
Comparing timedelta with dt.time in python
我有一个名为 df['inc_cr_date']
的 pandas 系列,其日期格式为 2017-10-27 08:00:26.808
。
我想比较此列的日期和时间是否高于 18:30。问题是如果我使用下面的代码:
#All the condtions can be reduced to one mask and result
days_one = ['Monday','Tuesday','Wednesday','Thursday']
days_two = days_one + ['Friday']
# Returns a boolean mask
m1 = df['inc_cr_date_day'].isin(days_one) & (df['inc_cr_date'].dt.hour > 18 ) & (df['inc_cr_date'].dt.minute > 30)
m2 = df['inc_cr_date_day'].isin(days_two) & (df['inc_cr_date'].dt.hour < 9 ) & (df['inc_cr_date'].dt.minute < 30)
# Repeated result can be stored in one variable
r1 = (df['inc_cr_date']+pd.Timedelta('1 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')
r2 = (df['inc_cr_date']+pd.Timedelta('0 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')
df['inc_cr_date_adjusted'] = np.select([
m1, m2,
(df['inc_cr_date_day'] == 'Saturday'),
(df['inc_cr_date_day'] == 'Sunday'),
((df['inc_cr_date_day'] == 'Friday')& (df['inc_cr_date'].dt.hour > 18 ) & df['inc_cr_date'].dt.minute > 30),
],
[r1, r2,
(df['inc_cr_date']+pd.Timedelta('2 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes'),
(df['inc_cr_date']+pd.Timedelta('1 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes'),
(df['inc_cr_date']+pd.Timedelta('3 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')
],
df['inc_cr_date'])
这会让我得到模棱两可的结果,因为第一个条件可能为真但第二个条件可能不为真。我如何将 ['inc_cr_date'] 列与 18:30 进行比较,而不是将分钟和小时分开?
我也试过使用 pandas.DataFrame.between_time 如下:
start = datetime.time(18,30,0)
end = datetime.time(23,59,0)
df['inc_cr_date'].between_time(start, end) )
但是出现错误:
TypeError: Index must be DatetimeIndex
即使我这样做:
df['inc_cr_date'] = pd.DatetimeIndex(df['inc_cr_date'])
数据框如下:
inc_cr_date inc_cr_date_day
0 2017-10-26 21:59:28.075 Thursday 2017-10-27
1 2017-10-21 16:49:58.722 Saturday 2017-10-23
2 2017-10-11 09:30:05.258 Wednesday 2017-10-11
输出应该是这样的:
inc_cr_date inc_cr_date_day inc_cr_date_adjusted
0 2017-10-26 21:20:28.075 Thursday 2017-10-27 09:30:00.000
1 2017-10-21 16:49:58.722 Saturday 2017-10-23 09:30:00.000
2 2017-10-11 09:30:05.258 Wednesday 2017-10-11 09:30:05.258
请指教。谢谢。
这个怎么样?
df['timeFlag'] = df['inc_cr_date'].apply(lambda x: 1 if x.time() > datetime.time(18, 30, 0) else 0)
在您的示例中,您可以更改这些行:
# Returns a boolean mask
m1 = df['inc_cr_date_day'].isin(days_one) & (df['inc_cr_date'].dt.hour > 18 ) & (df['inc_cr_date'].dt.minute > 30)
m2 = df['inc_cr_date_day'].isin(days_two) & (df['inc_cr_date'].dt.hour < 9 ) & (df['inc_cr_date'].dt.minute < 30)
至:
# Returns a boolean mask
m1 = df['inc_cr_date_day'].isin(days_one) & (df['inc_cr_date'].apply(lambda x: 1 if x.time() > datetime.time(18, 30,0) else 0))
m2 = df['inc_cr_date_day'].isin(days_two) & (df['inc_cr_date'].apply(lambda x: 1 if x.time() > datetime.time(18, 30,0) else 0))
我有一个名为 df['inc_cr_date']
的 pandas 系列,其日期格式为 2017-10-27 08:00:26.808
。
我想比较此列的日期和时间是否高于 18:30。问题是如果我使用下面的代码:
#All the condtions can be reduced to one mask and result
days_one = ['Monday','Tuesday','Wednesday','Thursday']
days_two = days_one + ['Friday']
# Returns a boolean mask
m1 = df['inc_cr_date_day'].isin(days_one) & (df['inc_cr_date'].dt.hour > 18 ) & (df['inc_cr_date'].dt.minute > 30)
m2 = df['inc_cr_date_day'].isin(days_two) & (df['inc_cr_date'].dt.hour < 9 ) & (df['inc_cr_date'].dt.minute < 30)
# Repeated result can be stored in one variable
r1 = (df['inc_cr_date']+pd.Timedelta('1 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')
r2 = (df['inc_cr_date']+pd.Timedelta('0 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')
df['inc_cr_date_adjusted'] = np.select([
m1, m2,
(df['inc_cr_date_day'] == 'Saturday'),
(df['inc_cr_date_day'] == 'Sunday'),
((df['inc_cr_date_day'] == 'Friday')& (df['inc_cr_date'].dt.hour > 18 ) & df['inc_cr_date'].dt.minute > 30),
],
[r1, r2,
(df['inc_cr_date']+pd.Timedelta('2 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes'),
(df['inc_cr_date']+pd.Timedelta('1 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes'),
(df['inc_cr_date']+pd.Timedelta('3 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')
],
df['inc_cr_date'])
这会让我得到模棱两可的结果,因为第一个条件可能为真但第二个条件可能不为真。我如何将 ['inc_cr_date'] 列与 18:30 进行比较,而不是将分钟和小时分开?
我也试过使用 pandas.DataFrame.between_time 如下:
start = datetime.time(18,30,0)
end = datetime.time(23,59,0)
df['inc_cr_date'].between_time(start, end) )
但是出现错误:
TypeError: Index must be DatetimeIndex
即使我这样做:
df['inc_cr_date'] = pd.DatetimeIndex(df['inc_cr_date'])
数据框如下:
inc_cr_date inc_cr_date_day
0 2017-10-26 21:59:28.075 Thursday 2017-10-27
1 2017-10-21 16:49:58.722 Saturday 2017-10-23
2 2017-10-11 09:30:05.258 Wednesday 2017-10-11
输出应该是这样的:
inc_cr_date inc_cr_date_day inc_cr_date_adjusted
0 2017-10-26 21:20:28.075 Thursday 2017-10-27 09:30:00.000
1 2017-10-21 16:49:58.722 Saturday 2017-10-23 09:30:00.000
2 2017-10-11 09:30:05.258 Wednesday 2017-10-11 09:30:05.258
请指教。谢谢。
这个怎么样?
df['timeFlag'] = df['inc_cr_date'].apply(lambda x: 1 if x.time() > datetime.time(18, 30, 0) else 0)
在您的示例中,您可以更改这些行:
# Returns a boolean mask
m1 = df['inc_cr_date_day'].isin(days_one) & (df['inc_cr_date'].dt.hour > 18 ) & (df['inc_cr_date'].dt.minute > 30)
m2 = df['inc_cr_date_day'].isin(days_two) & (df['inc_cr_date'].dt.hour < 9 ) & (df['inc_cr_date'].dt.minute < 30)
至:
# Returns a boolean mask
m1 = df['inc_cr_date_day'].isin(days_one) & (df['inc_cr_date'].apply(lambda x: 1 if x.time() > datetime.time(18, 30,0) else 0))
m2 = df['inc_cr_date_day'].isin(days_two) & (df['inc_cr_date'].apply(lambda x: 1 if x.time() > datetime.time(18, 30,0) else 0))