我有一个名为df['inc_cr_date']
的大熊猫系列,其格式为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'])
这会让我产生模棱两可的结果,因为第一个条件可能是真的,但第二个条件不可能。如何将[&#39; inc_cr_date&#39;]列与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'])
Dataframe如下所示:
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
请指教。感谢。
答案 0 :(得分:1)
这个怎么样?
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))