프로모션별 평균 할인율, 매출, 주요 고객 , 주요 구매된 카테고리, 결제 유형 등
# promo_code가 있는 행만 필터링
promo_df = transactions_df[transactions_df['promo_code'] != 'None']
promo_df['promo_code'].value_counts()
# 할인율 컬럼 추가
promo_df['discount_rate'] = promo_df['promo_amount'] / promo_df['total_amount']
# 프로모션 코드별 평균 할인율 계산avg_discount_by_code = promo_df.groupby('promo_code')['discount_rate'].mean().sort_values(ascending=False)
print(avg_discount_by_code)
transaction에서 promo_mount와 total_amount의 비율 확인해서 할인율 추정 가능
| 프로모션 코드 | 사용 건수 | 평균 할인율 (%) |
|---|---|---|
AZ2022 | 89,227 | 1.93% |
BUYMORE | 66,835 | 1.93% |
WEEKENDSERU | 61,941 | 1.92% |
XX2022 | 44,744 | 1.92% |
LIBURDONG | 20,965 | 1.91% |
WEEKENDMANTAP | 20,448 | 1.92% |
SC2022 | 11,271 | 3.95% |
STARTUP | 11,105 | 3.98% |
- 할인율이 높을수록 사용건수가 적음(많이 뿌릴 땐 낮은 단가로, 적게 뿌릴 땐 높은 단가로)
- 할인율이 높을땐 특정고객에게만.(적은 인원수)
# 프로모션 코드별 + 결제수단별 건수 집계
promo_payment_counts = promo_df.groupby(['promo_code', 'payment_method']).size().unstack(fill_value=0)
# 정렬
promo_payment_counts = promo_payment_counts.sort_index()
print(promo_payment_counts)
# 비율로 변환 (행 기준 → 각 프로모션별 합계로 나눔)
percentages = promo_payment_counts.div(promo_payment_counts.sum(axis=1), axis=0) * 100
# 소수점 두 자리로 포맷
percentages = percentages.round(2)
print(percentages)
| 프로모션 코드 | Credit Card | Debit Card | Gopay | LinkAja | OVO |
|---|---|---|---|---|---|
| AZ2022 | 31,339 | 14,279 | 17,934 | 7,868 | 17,807 |
| BUYMORE | 23,521 | 10,714 | 13,374 | 5,915 | 13,311 |
| LIBURDONG | 7,264 | 3,382 | 4,345 | 1,822 | 4,152 |
| SC2022 | 3,955 | 1,854 | 2,284 | 990 | 2,188 |
| STARTUP | 3,861 | 1,802 | 2,281 | 1,010 | 2,151 |
| WEEKENDMANTAP | 7,263 | 3,316 | 4,038 | 1,746 | 4,085 |
| WEEKENDSERU | 21,619 | 9,884 | 12,524 | 5,532 | 12,382 |
| XX2022 | 15,682 | 7,201 | 8,916 | 3,955 | 8,990 |
비율로 나타내면
| 프로모션 코드 | Credit Card | Debit Card | Gopay | LinkAja | OVO |
|---|---|---|---|---|---|
| AZ2022 | 35.12% | 16.00% | 20.10% | 8.82% | 19.96% |
| BUYMORE | 35.19% | 16.03% | 20.01% | 8.85% | 19.92% |
| WEEKENDSERU | 34.90% | 15.96% | 20.22% | 8.93% | 19.99% |
| XX2022 | 35.05% | 16.09% | 19.93% | 8.84% | 20.09% |
| LIBURDONG | 34.65% | 16.13% | 20.73% | 8.69% | 19.80% |
| WEEKENDMANTAP | 35.52% | 16.22% | 19.75% | 8.54% | 19.98% |
| SC2022 | 35.09% | 16.45% | 20.26% | 8.78% | 19.41% |
| STARTUP | 34.77% | 16.23% | 20.54% | 9.10% | 19.37% |
프로모션 코드별 결제 수단 비율이 거의 같음
→ 프로모션 코드와 결제수단 사이에 유의미한 상관관계가 없다
(독립성 검정 해볼까? ⇒ 프로모션 코드와 결제수단은 독립적이다)
STARTUP은 회원가입시 사용할 수 있는 코드이다.| 프로모션 코드 | 건수 | 평균 | 표준편차 | 최소 | 25% | 중앙값 | 75% | 최대 |
|---|---|---|---|---|---|---|---|---|
| AZ2022 | 89,227 | 658.77 | 502.23 | 0.0 | 234.0 | 563.0 | 1,005.0 | 2,209.0 |
| BUYMORE | 66,834 | 659.53 | 504.85 | 0.0 | 232.0 | 562.0 | 1,009.0 | 2,217.0 |
| WEEKENDSERU | 61,941 | 625.45 | 513.63 | 0.0 | 186.0 | 519.0 | 980.0 | 2,212.0 |
| XX2022 | 44,744 | 660.72 | 503.57 | 0.0 | 234.0 | 569.0 | 1,008.0 | 2,187.0 |
| LIBURDONG | 20,965 | 620.48 | 505.58 | 0.0 | 189.0 | 519.0 | 967.0 | 2,201.0 |
| WEEKENDMANTAP | 20,448 | 626.83 | 512.24 | 0.0 | 193.0 | 525.0 | 972.0 | 2,198.0 |
| SC2022 | 11,271 | 660.32 | 504.04 | 0.0 | 235.0 | 562.0 | 1,010.0 | 2,161.0 |
| STARTUP | 11,105 | 666.60 | 507.30 | 0.0 | 234.0 | 576.0 | 1,014.0 | 2,185.0 |
STARTUP이 평균 오히려 제일 큼(가장 늦게 사용)
코드
# aptc = Add to Promo + Transaction + Customer
aptc = pd.merge(apt, customer_df, how='left', on='customer_id')
# first_join_date 컬럼을 datetime 형식으로 변환
aptc['first_join_date'] = pd.to_datetime(aptc['first_join_date'])
# 시간대 없애기
aptc['created_at'] = aptc['created_at'].dt.tz_localize(None)
# 결제일 - 가입일 계산
aptc['date_diff'] = (aptc['created_at'] - aptc['first_join_date']).dt.days
# 프로모션별 평균 day 차이
aptc.groupby('promo_code')['date_diff'].mean().reset_index().sort_values('date_diff', ascending=False)
# 프로모션별 day차이 describe
aptc.groupby('promo_code')['date_diff'].describe()

5번 사용한 99915 확인해보면

# 고객별로 promocode 몇 번 썼는지 count
promo_usage = aptc.groupby(['customer_id', 'promo_code']).size().reset_index(name='use_count')
# startup promo 몇 번 썼는지 count promo_usage[promo_usage['promo_code'] == 'STARTUP']
# startup promo를 2번 이상 썼는지 확인
promo_usage[(promo_usage['promo_code'] == 'STARTUP') & (promo_usage['use_count'] >= 2)]
# 5번 사용한 경우(customer_id = 99915) 확인
aptc[(aptc['customer_id'] == 99915) & (aptc['promo_code'] == 'STARTUP')][
['event_name', 'session_id', 'event_time',
'created_at', 'promo_code', 'date_diff']].T
WEEKENDMANTAP, WEEKENDSERU, LIBURDONG는 주말 한정(공휴일) 할인쿠폰일 것이다# WEEKENDMANTAP
weekend_df = aptc[aptc['promo_code'] == 'WEEKENDMANTAP'].copy()
# 사용 날짜 요일 이름으로 나타내기
weekend_df['day_of_week'] = weekend_df['created_at'].dt.day_name()
weekend_df['day_of_week'].value_counts()
# WEEKENDSERU
weekend_df = aptc[aptc['promo_code'] == 'WEEKENDSERU'].copy()
weekend_df['day_of_week'] = weekend_df['created_at'].dt.day_name()
weekend_df['day_of_week'].value_counts()
# LIBURDONG
libur_df = aptc[aptc['promo_code'] == 'LIBURDONG'].copy()
libur_df['day_of_week'] = libur_df['created_at'].dt.day_name()
libur_df['day_of_week'].value_counts()
Sunday 32910
Saturday 29031
Libur = 휴일, dong은 감탄사Sunday 11139
Saturday 9826

SC2022, AZ2022, XX2022 는 특정 시기(캠페인-2022-)코드일 것이다
2022가 있어서 2022년 특정 프로모션일 것이라 예상했는데 그것과 관계없이 꾸준히 이루어 짐을 확인할 수 있다.
# 비교할 프로모션 코드 목록을 정의
codes = ['SC2022', 'AZ2022', 'XX2022']
# 전체 그래프 크기 설정
plt.figure(figsize=(12, 5))
# 각 프로모션 코드에 대해 반복
for code in codes:
# 해당 코드에 해당하는 행만 필터링 (복사본 생성)
df = aptc[aptc['promo_code'] == code].copy()
# created_at 날짜에서 '연-월'만 추출하여 새로운 'month' 컬럼 생성
df['month'] = df['created_at'].dt.to_period('M')
# 월별 사용 건수를 계산, 월 순서대로 정렬
monthly_counts = df['month'].value_counts().sort_index()
# 인덱스를 Timestamp 형식으로 바꿈
monthly_counts.index = monthly_counts.index.to_timestamp()
# 라인 그래프로 월별 사용량 시각화 monthly_counts.plot(label=code)
# 그래프 제목, 축 레이블, 범례, 그리드 설정
plt.title("월별 프로모션 사용량: SC2022 / AZ2022 / XX2022")
plt.xlabel("월")
plt.ylabel("사용 건수")
plt.legend()
plt.grid(True)
plt.tight_layout()
# 그래프 출력
plt.show()