이전 내용
[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 3
이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 2이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 1프로젝트 개요 2차 프로젝트를 시작하게 되었다.이번에 해야할
puppy-foot-it.tistory.com
시각화 작업
연령대별 분석
1. 각 지역의 연령별 방문자수 및 참여자수
기존에 만들어둔 누적 막대그래프 생성 코드를 응용하여 누적막대그래프 생성
- 연령별 방문자수 누적 막대그래프
# 데이터 집계 및 병합
off_df_age = off_df.groupby(['연령대', '날짜', '지역']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()
# 컬럼 이름 변경
off_df_age.rename(columns={'지역': 'CITY', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '연령대': 'AGE'}, inplace=True)
# 날짜를 datetime으로 형변환
off_df_age['DATE'] = pd.to_datetime(off_df_age['DATE'])
# 참여율 칼럼 추가
off_df_age['P_Ratio'] = (off_df_age['PART'] / off_df_age['VISITORS']) * 100
# 'DATE'를 월 단위로 그룹화하고 각 지역별 방문자 수를 합산
monthly_visit_age = off_df_age.groupby(['CITY', 'AGE', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_age.pivot_table(index='CITY', columns='AGE', values='VISITORS', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
bottom_values += pivoted_data[age]
# 그래프 꾸미기
plt.title('연령대별 방문자수') # 제목 추가
plt.xlabel('지역') # x축 라벨 추가
plt.ylabel('누적 방문자수') # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
- 연령별 참여자수 누적 막대그래프
# 'DATE'를 월 단위로 그룹화하고 각 지역별 참여자 수를 합산
monthly_part_age = off_df_age.groupby(['CITY', 'AGE', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_age.pivot_table(index='CITY', columns='AGE', values='PART', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
bottom_values += pivoted_data[age]
# 그래프 꾸미기
plt.title('연령대별 참여자수') # 제목 추가
plt.xlabel('지역') # x축 라벨 추가
plt.ylabel('누적 참여자수') # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
2. 연령대별 방문 및 참여 비율
- 연령대별 방문 비율 (파이차트)
# 데이터 집계
vis_age = off_df_age.groupby(['AGE'])['VISITORS'].sum().reset_index()
labels = vis_age['AGE'].unique()
explode = [0.1 for _ in range(len(labels))] # 모든 섹터를 약간 부풀리기
# 색상 팔레트 설정
colors = sns.color_palette("Set2", len(labels))
plt.pie(data = vis_age, x='VISITORS', labels=labels, autopct='%.1f%%',startangle=260,
colors=colors, explode=explode, shadow=True)
plt.title("연령대별 방문율")
plt.show()
▶ 가상 데이터라 그런지 연령대별로 데이터가 균등하게 나눠져 있음을 알 수 있다.
- 월간 연령대별 방문자수 그래프
# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_visit_age, x='DATE', y='VISITORS', hue='AGE', palette='Set1')
# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 연령대별 방문자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
- 월간 연령대별 참여자수 그래프
# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_part_age, x='DATE', y='PART', hue='AGE', palette='Set2')
# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 연령대별 참여자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
- 연령대별 참여 비율 (파이차트)
# 데이터 집계
part_age = off_df_age.groupby(['AGE'])['PART'].sum().reset_index()
labels = part_age['AGE'].unique()
explode = [0.1 for _ in range(len(labels))] # 모든 섹터를 약간 부풀리기
# 색상 팔레트 설정
colors = sns.color_palette("Set3", len(labels))
plt.pie(data = part_age, x='PART', labels=labels, autopct='%.1f%%',startangle=260,
colors=colors, explode=explode, shadow=True)
plt.title("연령대별 참여율")
plt.show()
▶ 가상 데이터라 그런지 연령대별로 데이터가 균등하게 나눠져 있음을 알 수 있다.
- 각 캠페인의 연령대별 방문자수 누적 막대그래프 그리기
# 데이터 집계 및 병합
off_df_ev_age = off_df.groupby(['연령대', '날짜', '이벤트 종류']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()
# 컬럼 이름 변경
off_df_ev_age.rename(columns={'이벤트 종류': 'CAMP', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '연령대': 'AGE'}, inplace=True)
# 날짜를 datetime으로 형변환
off_df_ev_age['DATE'] = pd.to_datetime(off_df_ev_age['DATE'])
# 참여율 칼럼 추가
off_df_ev_age['P_Ratio'] = (off_df_ev_age['PART'] / off_df_ev_age['VISITORS']) * 100
# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_visit_ev_age = off_df_ev_age.groupby(['CAMP', 'AGE', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_ev_age.pivot_table(index='CAMP', columns='AGE', values='VISITORS', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
bottom_values += pivoted_data[age]
# 그래프 꾸미기
plt.title('캠페인-연령대별 방문자수') # 제목 추가
plt.xlabel('캠페인') # x축 라벨 추가
plt.ylabel('누적 방문자수') # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
- 각 캠페인의 연령대별 참여자수 누적 막대그래프 그리기
# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_part_ev_age = off_df_ev_age.groupby(['CAMP', 'AGE', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_ev_age.pivot_table(index='CAMP', columns='AGE', values='PART', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for age in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[age], bottom=bottom_values, label=age)
bottom_values += pivoted_data[age]
# 그래프 꾸미기
plt.title('캠페인-연령대별 참여자수') # 제목 추가
plt.xlabel('캠페인') # x축 라벨 추가
plt.ylabel('누적 참여자수') # y축 라벨 추가
plt.legend(title='연령대', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
시각화 작업
성별 데이터 분석
이번에는 성별 데이터를 이용한 데이터 시각화를 진행해 본다.
- 각 지역의 성별별 방문자수 누적막대그래프
# 데이터 집계 및 병합
off_df_gender = off_df.groupby(['성별', '날짜', '지역']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()
# 컬럼 이름 변경
off_df_gender.rename(columns={'지역': 'CITY', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '성별': 'GENDER'}, inplace=True)
# 날짜를 datetime으로 형변환
off_df_gender['DATE'] = pd.to_datetime(off_df_gender['DATE'])
# 참여율 칼럼 추가
off_df_gender['P_Ratio'] = (off_df_gender['PART'] / off_df_gender['VISITORS']) * 100
# 'DATE'를 월 단위로 그룹화하고 각 지역별 방문자 수를 합산
monthly_visit_gender = off_df_gender.groupby(['CITY', 'GENDER', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_gender.pivot_table(index='CITY', columns='GENDER', values='VISITORS', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
bottom_values += pivoted_data[gender]
# 그래프 꾸미기
plt.title('성별별 방문자수') # 제목 추가
plt.xlabel('지역') # x축 라벨 추가
plt.ylabel('누적 방문자수') # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
- 각 지역의 성별별 참여자수 누적막대그래프
# 'DATE'를 월 단위로 그룹화하고 각 지역별 참여자 수를 합산
monthly_part_gender = off_df_gender.groupby(['CITY', 'GENDER', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_gender.pivot_table(index='CITY', columns='GENDER', values='PART', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
bottom_values += pivoted_data[gender]
# 그래프 꾸미기
plt.title('성별별 참여자수') # 제목 추가
plt.xlabel('지역') # x축 라벨 추가
plt.ylabel('누적 참여자수') # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
- 월간 성별별 방문자수 라인 차트
# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_visit_gender, x='DATE', y='VISITORS', hue='GENDER', palette='Set1')
# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 성별별 방문자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
- 월간 성별별 참여자수 라인 차트
# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=monthly_part_gender, x='DATE', y='PART', hue='GENDER', palette='Set2')
# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('월간 성별별 참여자수')
plt.xlabel('날짜')
plt.ylabel('수')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
- 각 성별의 캠페인 방문자수 누적 막대그래프
# 데이터 집계 및 병합
off_df_ev_gender = off_df.groupby(['성별', '날짜', '이벤트 종류']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()
# 컬럼 이름 변경
off_df_ev_gender.rename(columns={'이벤트 종류': 'CAMP', '방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '성별': 'GENDER'}, inplace=True)
# 날짜를 datetime으로 형변환
off_df_ev_gender['DATE'] = pd.to_datetime(off_df_ev_gender['DATE'])
# 참여율 칼럼 추가
off_df_ev_gender['P_Ratio'] = (off_df_ev_gender['PART'] / off_df_ev_gender['VISITORS']) * 100
# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_visit_ev_gender = off_df_ev_gender.groupby(['CAMP', 'GENDER', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_visit_ev_gender.pivot_table(index='CAMP', columns='GENDER', values='VISITORS', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
bottom_values += pivoted_data[gender]
# 그래프 꾸미기
plt.title('캠페인-성별별 방문자수') # 제목 추가
plt.xlabel('캠페인') # x축 라벨 추가
plt.ylabel('누적 방문자수') # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
- 각 성별의 캠페인 참여자수 누적 막대그래프
# 'DATE'를 월 단위로 그룹화하고 각 캠페인별 참여자 수를 합산
monthly_part_ev_gender = off_df_ev_gender.groupby(['CAMP', 'GENDER', pd.Grouper(key='DATE', freq='M')])['PART'].sum().reset_index()
# 그래프를 그릴 수 있도록 데이터 피벗
pivoted_data = monthly_part_ev_gender.pivot_table(index='CAMP', columns='GENDER', values='PART', fill_value=0)
# 누적 막대그래프 생성
plt.figure(figsize=(10, 5))
# 각 연령대별로 누적 막대 그래프를 그리기 위한 시작 지점
bottom_values = pd.Series([0] * pivoted_data.shape[0], index=pivoted_data.index)
# 각 연령대별로 누적 값 추가
for gender in pivoted_data.columns:
plt.bar(pivoted_data.index, pivoted_data[gender], bottom=bottom_values, label=gender)
bottom_values += pivoted_data[gender]
# 그래프 꾸미기
plt.title('캠페인-성별별 참여자수') # 제목 추가
plt.xlabel('캠페인') # x축 라벨 추가
plt.ylabel('누적 참여자수') # y축 라벨 추가
plt.legend(title='성별', loc='best', bbox_to_anchor=(1, 1), ncol=1, fontsize=10) # 범례 설정
plt.xticks(rotation=45) # x축 라벨 회전
plt.tight_layout(rect=[0, 0, 0.85, 1]) # 레이아웃 조정하여 그래프 안쪽 공간 늘리기
plt.show() # 그래프 출력
지금까지 오프라인 캠페인 데이터 관련 변수들을 가지고 데이터분석 시각화 작업을 진행해 보았다.
아무래도 실제 데이터가 아닌 가상 데이터로 진행하다보니, 데이터가 큰 차이 없이 균등하다. 물론, 실제로도 이러한 상황이 진행될 수 있으므로, 굳이 데이터를 인위적으로 조작할 필요는 없을 것으로 보인다. (현재 데이터를 시각화해보는 게 더 큰 목적이므로)
물론, 날짜 데이터가 있기 때문에 이를 토대로 월별이 아닌, 요일별 데이터로 나눠 분석을 해볼 수도 있고, 더 다양한 분석 기법이 있다.
# 데이터 집계 및 병합
off_df_day = off_df.groupby(['성별', '날짜', '이벤트 종류']).agg({'방문자수': 'sum', '참여자수': 'sum'}).reset_index()
# 컬럼 이름 변경
off_df_day.rename(columns={'날짜': 'DATE', '이벤트 종류': 'CAMP', '성별': 'GENDER',
'방문자수': 'VISITORS', '참여자수': 'PART'}, inplace=True)
# 데이터의 날짜를 날짜 데이터로 형변환
off_df_day['DATE'] = pd.to_datetime(off_df_day['DATE'])
# 요일 정보 추가
off_df_day['DAY_OF_WEEK'] = off_df_day['DATE'].dt.day_name() # 요일 이름 추가
# 'DAY_OF_WEEK'와 '이벤트 종류', '성별'로 그룹화하고 참여자 수 합산
day_visit_ev_gender = off_df_day.groupby(['CAMP', 'GENDER', 'DAY_OF_WEEK'])['VISITORS'].sum().reset_index()
# 요일 순서 정렬
day_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
day_visit_ev_gender['DAY_OF_WEEK'] = pd.Categorical(day_visit_ev_gender['DAY_OF_WEEK'], categories=day_order, ordered=True)
# 데이터를 요일별로 정렬
day_visit_ev_gender = day_visit_ev_gender.sort_values(by='DAY_OF_WEEK').reset_index(drop=True)
# 시각화
plt.figure(figsize=(12, 9))
sns.lineplot(data=day_visit_ev_gender, x='DAY_OF_WEEK', y='VISITORS', hue='GENDER', palette='Set1')
# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('요일-성별별 방문자수')
plt.xlabel('요일')
plt.ylabel('수')
plt.xticks()
plt.grid(True)
plt.tight_layout()
plt.show()
# 시각화
plt.figure(figsize=(10, 5))
sns.barplot(data=day_visit_ev_gender, x='DAY_OF_WEEK', y='VISITORS', hue='GENDER', palette='Set2')
# 그래프 꾸미기
plt.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1))
plt.title('요일-성별별 방문자수')
plt.xlabel('요일')
plt.ylabel('수')
plt.xticks()
plt.grid(True)
plt.tight_layout()
plt.show()
다음에는 데이터를 토대로 머신러닝 작업을 진행해 본다.
다음 내용
[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 5
이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 4이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 3이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 2
puppy-foot-it.tistory.com
'[파이썬 Projects] > <파이썬 데이터 분석>' 카테고리의 다른 글
[파이썬] 프로젝트 : 웹 페이지 구축 - 3(데이터 시각화) (0) | 2025.03.20 |
---|---|
[파이썬] 프로젝트 : 웹 페이지 구축 - 2 (데이터 전처리, 시각화) (0) | 2025.03.20 |
[파이썬] 프로젝트 : 웹 페이지 구축 - 1 (가상데이터 생성) (0) | 2025.03.14 |
[파이썬] 자연어 처리 (NLP) - 네이버 뉴스 텍스트 분석(2) (0) | 2024.08.21 |
[워드클라우드] 코로나 뉴스 기사 (feat.주사기 마스킹) (2) | 2024.08.19 |