티스토리 뷰
영업일 (Business day, working day)
시작 날짜부터 끝 날짜까지 총 몇 일의 working day가 있는지 카운트
pd.bdate_range
import datetime
import pandas as pd
holidays_list = ['2022-05-05', '2022-05-08', '2022-06-01', '2022-06-06']
start_date = datetime.datetime.strptime('2022-05-01', "%Y-%m-%d").date()
end_date = datetime.datetime.strptime('2022-05-30', "%Y-%m-%d").date()
print (len(pd.bdate_range(start=start_date, end=end_date, freq='C', holidays=holidays_list)))
freq='C' 는 custom된 freq를 사용하겠다는 의미. weekmask나 holidays를 따로 사용해 주었을 경우 freq='C'라고 적어주어야함.
디폴트는 'B' (business daily)
[함수형태]
def foo(row):
start_date = row['시작일']
end_date = row['끝일']
l = len(pd.bdate_range(start=start_date, end=end_date, freq='C', holidays=holidays_list)))
return l
df['시작일'] = pd.to_datetime(df['시작일'], format='%Y%m%d')
df['끝일'] = pd.to_datetime(df['끝일'], format='%Y%m%d')
df['시작일-끝일'] = df.apply(foo, axis=1)
다음 영업일 찾기
np.is_busday
ONE_DAY = datetime.timedelta(days=1)
def next_business_day():
# today = datetime.date.today()
today = datetime.datetime.strptime('2022-07-08', "%Y-%m-%d").date()
next_day = today + ONE_DAY
while next_day in holidays_list_date or not np.is_busday(next_day):
next_day += ONE_DAY
return next_day
Data Frame에 적용 + lead time(지역별 배송 소요시간) 고려
ONE_DAY = datetime.timedelta(days=1)
def next_business_day_lead_time(row):
start_str = row['출고완료일']
lead_day = row['지역별배송소요시간'] / 24
cal_lead_day = datetime.timedelta(days=lead_day) # 이틀
exp_dlv_day = start_str + cal_lead_day
while exp_dlv_day in holidays_list_date or not np.is_busday(exp_dlv_day):
exp_dlv_day += ONE_DAY
return exp_dlv_day
df['출고완료일_소요시간'] = df.apply(next_business_day_lead_time, axis=1)
Data Frame에 적용 + weekmask 사용법 (토요일만 휴무일인 경우)
def cal_exp_dlv_date2(row, time_threshold):
start_str = row['입금확인일']
if row['입금확인시간'] >= datetime.datetime.strptime(time_threshold, '%H:%M:%S').time(): # time만 원하면 .time()
lead_day = 1
else:
lead_day = 0
exp_dlv_day = start_str.date()
# 입금확인일이 토요일인 경우 하루 추가.
if exp_dlv_day in holidays_list_date or not np.is_busday(exp_dlv_day, weekmask=[1, 1, 1, 1, 1, 0, 1]):
exp_dlv_day += ONE_DAY
while exp_dlv_day in holidays_list_date or not np.is_busday(exp_dlv_day, weekmask=[1, 1, 1, 1, 1, 0, 1]):
exp_dlv_day += ONE_DAY
for i in range(int(lead_day)):
exp_dlv_day += ONE_DAY
while exp_dlv_day in holidays_list_date or not np.is_busday(exp_dlv_day, weekmask=[1, 1, 1, 1, 1, 0, 1]):
exp_dlv_day += ONE_DAY
return exp_dlv_day
new_df['출고예정일자_new'] = new_df.apply(cal_exp_dlv_date2, time_threshold='21:00:00', axis=1)
holidays_list_date = [내가 정한 공휴일]
함수 설명:
- 만약 입금확인 시간이 21시 이상인 경우 lead_day는 1일, 아니면 0일
- exp_dlv_day라는 변수에 입금확인일의 날짜만 넣어줌.
- 만약, exp_dlv_day가 holidays_list_date/토요일일 경우 하루씩 추가해주면서 exp_dlv_day가 holidays_list_date/토요일이 아니게 만듦.
- 그리고 나서 위에서 구한 lead_day를 이용해 lead_day만큼 더해가면서 exp_dlv_day가 holidays_list_date/토요일이 아니게 만듦.
- 최종적으로 구해진 exp_dlv_day값 리턴.
'pandas' 카테고리의 다른 글
pd.read_xml을 사용해 xml파일을 dataframe으로 바꾸기 (0) | 2023.04.02 |
---|---|
split과 join을 이용해 문자열 자른 뒤 합치기(apply, lambda, axis) (0) | 2022.11.26 |
pd.to_datetime, strptime, strftime, (0) | 2022.07.15 |
group by 후 custom된 집계함수 사용 (0) | 2022.06.16 |
차집합, 교집합, drop_duplicates, duplicated, indicator (0) | 2022.03.07 |
댓글
- Total
- Today
- Yesterday
공지사항
최근에 올라온 글
글 보관함