# actual_duration (배송 실제 기간)
df['order_purchase_timestamp'] = pd.to_datetime(df['order_purchase_timestamp'], errors='coerce')
df['order_delivered_customer_date'] = pd.to_datetime(df['order_delivered_customer_date'], errors='coerce')
# (실제 배송 완료일 - 구매 일시) 계산하여 '일(Day)' 단위로 넣기
# .dt.days를 사용하여 숫자(정수)만 남깁니다.
df['actual_duration'] = (df['order_delivered_customer_date'] - df['order_purchase_timestamp']).dt.days
df['actual_duration']
# handling_duration (준비 기간)
df['order_purchase_timestamp'] = pd.to_datetime(df['order_purchase_timestamp'], errors='coerce')
df['order_delivered_carrier_date'] = pd.to_datetime(df['order_delivered_carrier_date'], errors='coerce')
# (물류센터출고일시 - 구매 일시) 계산하여 '일(Day)' 단위로 넣기
# .dt.days를 사용하여 숫자(정수)만 남깁니다.
df['handling_duration'] = (df['order_delivered_carrier_date'] - df['order_purchase_timestamp']).dt.days
df['handling_duration']
# transit_duration (운송 기간)
df['order_delivered_carrier_date'] = pd.to_datetime(df['order_delivered_carrier_date'], errors='coerce')
df['order_delivered_customer_date'] = pd.to_datetime(df['order_delivered_customer_date'], errors='coerce')
# (실제 배송 완료일 - 물류센터출고일시) 계산하여 '일(Day)' 단위로 넣기
# .dt.days를 사용하여 숫자(정수)만 남깁니다.
df['transit_duration'] = (df['order_delivered_customer_date'] - df['order_delivered_carrier_date']).dt.days
df['transit_duration']

배송기간 평균 12일, 최대 209일
# 1. 0보다 큰 데이터만 추출
data = df[df['actual_duration'] > 0]['actual_duration'].dropna()
# 2. 상/하위 5% 지점 및 평균 계산
low, high = data.quantile([0.05, 0.95])
trimmed_data = data[(data >= low) & (data <= high)]
t_mean, o_mean = trimmed_data.mean(), data.mean()
# 3. 시각화 (edgecolor='none'으로 빈틈 제거)
plt.figure(figsize=(10, 5))
sns.histplot(trimmed_data, bins=int(high), color='green', edgecolor='none', discrete=True)
#
# 4. 평균선 및 한글 레이블 (운영체제에 맞는 폰트 설정이 미리 되어있어야 함)
plt.axvline(t_mean, color='r', ls='--', label=f'절단 평균(90%): {t_mean:.2f}일')
plt.axvline(o_mean, color='black', ls=':', label=f'전체 평균: {o_mean:.2f}일')
plt.title('배송 기간 분포 (상/하위 5% 제외)')
plt.xlabel('배송 일수'); plt.ylabel('주문 건수')
plt.legend(); plt.show()
print(f"✔️ 절단 평균(90%): {t_mean:.2f}일")
print(f"✔️ 전체 평균: {o_mean:.2f}일")

이상치 빼고 (상위 5%, 하위 5%) 배송기간 평균을 보면 11일이고
이상치 제거 안 했을 때는 (절단하지 않았을 때)는 12일 정도 걸린다.
# 1. 카테고리별로 그룹화하여 평균 계산
avg_duration = df.groupby('product_category_name_english')['actual_duration'].mean()
# 2. 값이 큰 순서(내림차순)로 정렬하고 상위 5개만 추출
top_5_slowest = avg_duration.sort_values(ascending=False).head(5)
# 3. 결과 확인
print("--- 배송 평균 기간이 가장 긴 상위 5개 카테고리 ---")
print(top_5_slowest)


차트로 보면 이렇다.
office_furniture (사무용 가구)
[부피와 무게] 가구는 일반 택배가 아닌 화물 배송인 경우가 많다고 함. 크기가 크고 무거워 상차/하차 시간이 오래 걸리고, 전문 배송 기사님이 필요해 지연이 잦음.
christmas_supplies (크리스마스 용품)
[시즌성 폭주] 연말 특정 시기에 주문이 미친 듯이 몰리는 품목이라고 함. 택배 물동량이 가장 많을 때라 물류 터미널에서 병목 현상이 발생했을 가능성이 매우 높음.
security_and_services (보안 및 서비스)
[특수 처리] 금고나 보안 장비 등은 파손 위험이 크고 설치 서비스가 동반되는 경우가 있다고 함. 일반 상품보다 검수나 포장 과정이 까다로워 출고 자체가 늦어질 수 있음.
fashion_shoes (패션 신발)
[재고 및 해외 직구] 의외로 신발이 늦는 이유는 '해외 브랜드'인 경우가 많기 때문이라고 함. 또는 사이즈가 다양해 재고가 없는 상태에서 주문을 받고 나중에 수급하는 형식이면 지연이 발생함.
home_comfort_2 (홈 컴포트/침구류)
[대형 부피] 매트리스나 커다란 이불 솜 등이 포함된다고 함. 가구와 마찬가지로 부피가 커서 일반 배송망에서 처리 속도가 늦어지는 품목임.

사무용 가구가 엄청 오래걸리는 상품이 있긴 하지만 많지 않음
결국에는 배송기간은 15일에서 20일 정도 걸림

배송기간, 준비기간, 운송기간, 가격, 운송비, 무게로 상관관계를 살펴보았다.
배송기간과 운송기간, 운송비와 무게가 상관이 있어 보인다.

내가 원했던 우상향하는 그림은 아니다
무게는 10000, 배송기간은 20일까지 값이 모여있으니 저 범위를 더 살펴보고 싶었다

1. 배송기간이 7 ~ 8일에 주문 건수가 가장 높음 이후 완만해짐
2. 상품 무게 분포를 보면 대부분 2KG도 안 되는 가벼운 무게