2017-11-08 2 views
0

df, inc_cr_date_day 및 inc_cr_date의 두 열을 기반으로 df의 새 열 [ 'inc_cr_date_adjusted']을 만들지 만 아래 코드가 예상대로 작동하지 않습니다. 오류를주지는 않지만 토요일과 일요일의 작업 조건만으로 조건에 의해 정의 된대로 작동하지 않습니다. & 시간이 포함 된 조건은 요일이 합산되지 않기 때문에 작동하지 않습니다 (Timedelta ('1 일)') 다른 문제는 대부분의 날짜가 마지막 줄의 코드 "df [ 'inc_cr_date']를 가정해야한다는 것입니다.) "전혀 바뀌지는 않지만, 또한 붙어 있지는 않습니다.새 열의 조건 Numpy 및 Timedelta를 사용하여

내 조건은 요일과 inc_cr_date 열에 표시되는 & 분을 기준으로합니다. 시간 & 분은 &을 사용하여 나눈 9:30와 18:30입니다.

코드는 다음과 같습니다

df['inc_cr_date_day'] = df['inc_cr_date'].dt.weekday_name 

df['inc_cr_date_adjusted'] = np.select([(df['inc_cr_date_day'] == 'Saturday'),#condition working 
           (df['inc_cr_date_day'] == 'Sunday'),#condition working 
           ((df['inc_cr_date_day'] == 'Monday')& (df['inc_cr_date'].dt.hour > 18) & df['inc_cr_date'].dt.minute > 30), 
           ((df['inc_cr_date_day'] == 'Monday')& (df['inc_cr_date'].dt.hour < 9) & df['inc_cr_date'].dt.minute < 30), 
           ((df['inc_cr_date_day'] == 'Tuesday')& (df['inc_cr_date'].dt.hour > 18) & df['inc_cr_date'].dt.minute > 30), 
           ((df['inc_cr_date_day'] == 'Tuesday')& (df['inc_cr_date'].dt.hour < 9) & df['inc_cr_date'].dt.minute < 30), 
           ((df['inc_cr_date_day'] == 'Wednesday')& (df['inc_cr_date'].dt.hour > 18) & df['inc_cr_date'].dt.minute > 30), 
           ((df['inc_cr_date_day'] == 'Wednesday')& (df['inc_cr_date'].dt.hour < 9) & df['inc_cr_date'].dt.minute < 30), 
           ((df['inc_cr_date_day'] == 'Thursday')& (df['inc_cr_date'].dt.hour > 18) & df['inc_cr_date'].dt.minute > 30), 
           ((df['inc_cr_date_day'] == 'Thursday')& (df['inc_cr_date'].dt.hour < 9) & df['inc_cr_date'].dt.minute < 30), 
           ((df['inc_cr_date_day'] == 'Friday')& (df['inc_cr_date'].dt.hour > 18) & df['inc_cr_date'].dt.minute > 30), 
           ((df['inc_cr_date_day'] == 'Friday')& (df['inc_cr_date'].dt.hour < 9) & df['inc_cr_date'].dt.minute < 30)], 


          [(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('1 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes'), 
          (df['inc_cr_date']+pd.Timedelta('0 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('0 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('0 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('0 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']+pd.Timedelta('0 days')).dt.normalize() + pd.Timedelta('9 Hours 30 Minutes')], 

          df['inc_cr_date']) 

출력 (즉, 잘못) :

inc_cr_date,inc_cr_date_day,inc_cr_date_adjusted 
2017-10-26 21:59:28.075,Thursday,2017-10-26 09:30:00.000 #nok, adjusted should be 2017-10-27 and not 2017-10-26. 
2017-10-21 16:49:58.722,Saturday,2017-10-23 09:30:00.000 #ok 
2017-10-11 09:30:05.258,Wednesday,2017-10-11 09:30:00.000 #nok, in such situation the adjusted date should be same as inc_cr_date 

주셔서 감사합니다 입력에 대한 많은.

+0

이 같은 작업의 종료 조건에 괄호를 넣어 시도 할 수 있습니다 당신이 usinig'pd.cut' 비닝 갈 선호하는 것입니다. 어쩌면 조건에 약간의 모호함이있을 수 있습니다. – Dark

+0

나는 1 시간 이상 그것을 찾고 있는데 무엇이 잘못 될 수 있는지 찾을 수 없다. – Gonzalo

+0

나는 코드를 최적화했다. :) – Dark

답변

1

프로그래머는 가능한 한 많은 반복을 최소화하려고 노력해야합니다 (DRY 원칙에 따름). 우리는 .isin의 사용

#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 inc_cr_date_day inc_cr_date_adjusted 
0 2017-10-26 21:59: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 

보통 많은 condtions 때문에 여러 경기의 모호성을 만들 수 있습니다. 위의 코드가 여러분이 deisred 결과를 얻는 데 도움이되기를 바랍니다. 난 당신의 코드에 보면 조건의 우선 순위도없이 너무 너무 즉

((df['inc_cr_date_day'] == 'Monday')& (df['inc_cr_date'].dt.hour > 18) & (df['inc_cr_date'].dt.minute > 30)) 
+0

예를 들어 '2017-10-26 21 : 46 : 37.323'과 '2017-10-26 21 : 29 : 07.116'과 같이 '2017-10-27 09:30'과 같이 실행하면됩니다. : 00.000 "및"2017-10-26 21 : 29 : 07.116 ". 그들이 같은 시간을 가져야 할 때 -> "2017-10-27 09 : 30 : 00.000". 아마도 시간과 분에 대한 조건이 HH : MM이 아닌 별개의 조건으로 보였기 때문일 수 있습니다! – Gonzalo

+0

하지만 코드가 이전보다 정확한 결과를 제공합니다. 즉, – Gonzalo

+0

입니다. 아마도 '2017-10-26 21 : 29 : 07.116'은 어떤 조건도 충족하지 못할 수도 있습니다. 시간은> 18이지만 분은 30 미만입니다. 위의 방법을 사용하여 결과를 얻을 수 있습니다. 나는 과제를 써야한다. 따라서 여기에서 더 많은 조치를 취할 수 있습니다. 좋은 하루 되세요. 해결책이 도움이된다면 투표하는 것을 잊지 마십시오. :) – Dark