TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 데이터 분석>

[파이썬] 프로젝트 : 웹 페이지 구축 - 2 (데이터 전처리, 시각화)

by 기록자_Recordian 2025. 3. 20.
728x90
반응형
이전 내용

 

 

[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 1

프로젝트 개요 2차 프로젝트를 시작하게 되었다.이번에 해야할 프로젝트는 데이터를 이용한 대시보드 웹 페이지를 구축하는 것인데, 해당 대시보드에는 데이터를 분석하여 시각화 하는 작업이

puppy-foot-it.tistory.com


데이터 전처리, 시각화하기
1. 오프라인 데이터
1-1: 데이터 로드하여 살펴보기

 

이제 가상의 데이터를 만들었으므로, 이를 이용해서 어떤 변수를 활용해 데이터 분석을 할지, 분석된 데이터로 어떻게 시각화를 할지를 고민해야 할 차례다.

변수를 선택한 다음에는 실제 데이터 분석에 사용될 수 있도록 전처리 하는 과정이 꼭 선행되어야 한다는 것도 잊지 말아야 한다.

데이터는 오프라인 캠페인을 진행한 오프라인 데이터, 온라인 마케팅을 진행한 온라인 마케팅 지표 데이터가 있다.

먼저, 상대적으로 변수가 적은 오프라인 데이터를 불러와서 작업해 보려 한다.

※ 결과를 바로 바로 확인할 수 있도록 주피터노트북을 통해 진행하고, 후에 VSCode에 옮겨 넣을 계획이다.

 

◆ 필요한 라이브러리 import

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

 

◆ 한글, 마이너스 깨짐 해결

from matplotlib import rc
plt.rcParams['font.family'] = "Malgun Gothic"
plt.rcParams['axes.unicode_minus'] = False

 

◆ 오프라인 데이터 칼럼 확인하기

off_df = pd.read_csv('./recycling_off.csv')
off_df.head()

 

먼저 범주형 데이터인 지역, 연령대, 성별, 이벤트 종류를 확인해 본다.

- 지역: 캠페인을 진행한 지역

cities = off_df['지역'].unique()
cities

- 연령대: 캠페인 진행 시 방문한 사람들의 연령대 구분

ages = off_df['연령대'].unique()
ages

- 이벤트 종류: 진행한 이벤트의 종류

events = off_df['이벤트 종류'].unique()
events

 

수치형 데이터들의 정보도 확인해 본다.

off_df.describe()

 

해당 데이터셋의 전체 정보를 확인해 본다.

off_df.info()

▶ 결측치가 없이 모든 행에 데이터가 있는 것으로 확인된다.


일자별로 각 지역의 방문자수, 참여자수 합계와 참여비율 구해보기

 

지역별 데이터 분석 및 시각화를 위해 일자별로 각 지역의 데이터 합계를 내본다.

이를 위해, 방문자수와 참여자수는 지역과 날짜 기준으로 groupby를 하여 더해주고 새로운 데이터프레임으로 생성해 준다.

visitors_by_ct = off_df.groupby(['지역', '날짜'])[['방문자수']].sum().reset_index()
parties_by_ct = off_df.groupby(['지역', '날짜'])[['참여자수']].sum().reset_index()

# 두 집계를 합침.
off_df_ct = pd.merge(visitors_by_ct, parties_by_ct, on=['지역', '날짜'], how='outer')

off_df_ct.rename(columns={'방문자수': 'VISITORS', '참여자수': 'PART', '날짜': 'DATE', '지역': 'CITY'}, inplace=True)

# 참여율 칼럼 추가
off_df_ct['P_Ratio'] = (off_df_ct['PART'] / off_df_ct['VISITORS']) * 100

# 칼럼 순서 변경
column_order = ['DATE', 'CITY', 'VISITORS', 'PART', 'P_Ratio']

# 데이터프레임 컬럼 순서 재정렬
off_df_ct = off_df_ct.reindex(columns=column_order) 

# 날짜 순서로 정렬
off_df_ct = off_df_ct.sort_values(['DATE'], ascending=True)

# 결과 출력
off_df_ct.head()

 

  • 방문자 수 집계:
    visitors_by_ct = off_df.groupby(['지역', '날짜'])[['방문자수']].sum().reset_index():
    off_df DataFrame에서 '지역'과 '날짜'를 기준으로 그룹화하고, '방문자수'의 합계를 계산하여 새로운 DataFrame으로 생성합니다. reset_index()를 사용하여 인덱스가 초기화된다.
  • 참여자 수 집계:
    parties_by_ct = off_df.groupby(['지역', '날짜'])[['참여자수']].sum().reset_index():
    같은 방식으로 '참여자수'를 그룹화하여 합계를 계산한 후, 새로운 DataFrame으로 생성한다.
  • 두 집계 데이터 결합:
    off_df_ct = pd.merge(visitors_by_ct, parties_by_ct, on=['지역', '날짜'], how='outer'):
    앞서 계산한 두 DataFrame을 '지역'과 '날짜'를 키로 하여 외부 조인(outer join) 방식으로 결합한다. 이를 통해 두 데이터는 주어진 키에 따라 합쳐지고, 추가적인 지역과 날짜의 데이터도 포함된다.
  • 컬럼 이름 변경:
    off_df_ct.rename(...):
    결합된 DataFrame의 컬럼 이름을 더 이해하기 쉽게 변경한다. '방문자수'는 'VISITORS', '참여자수'는 'PART', '날짜'는 'DATE', '지역'은 'CITY'로 변경된다.
  • 참여율 계산:
    off_df_ct['P_Ratio'] = (off_df_ct['PART'] / off_df_ct['VISITORS']) * 100:
    'PART'와 'VISITORS'를 사용하여 참여율을 계산하고, 이를 'P_Ratio'라는 새로운 컬럼에 저장한다. 참여율은 참여자 수를 방문자 수로 나눈 값에 100을 곱하여 백분율로 표현된다.
  • 컬럼 순서 변경:
    column_order = ['DATE', 'CITY', 'VISITORS', 'PART', 'P_Ratio']:
    최종적으로 표현할 컬럼의 순서를 정의한다.
  • 데이터프레임 순서 재정렬:
    off_df_ct = off_df_ct.reindex(columns=column_order):
    reindex 메소드를 사용하여 DataFrame의 컬럼 순서를 변경한다.
  • 데이터프레임 순서 재정렬: off_df_ct = off_df_ct.sort_values(['DATE'], ascending=True): sort_values를 사용하여 날짜('DATE') 기준으로 데이터프레임 순서를 재정렬 한다.
  • 결과 출력:
    off_df_ct.head():
    생성된 off_df_ct DataFrame의 첫 다섯 행을 출력하여 결과를 확인한다.


데이터 시각화
1. 지역별 방문자 & 참여자

 

1. 일자별 전체 방문자수와 참여자수 보기

# 일자별 전체 방문자수와 참여자수 보기

labels = ['VISITORS', 'PART']

fig = plt.figure()
for label in labels:
    x = off_df_ct['DATE']
    y = off_df_ct[label]  # 수정: 각 레이블에 따라 y값을 개별적으로 설정합니다.
    sns.lineplot(x=x, y=y, label=label)

plt.legend()
plt.title('일자별 방문자수와 참여자수')  # 제목 추가
plt.xlabel('날짜')  # x축 라벨 추가
plt.ylabel('수')  # y축 라벨 추가
plt.xticks(rotation=45)  # x축 날짜 라벨을 기울여서 가독성 향상
plt.show()  # 그래프 출력

▶ 시각화를 했으나, 날짜가 많아서 너무 촘촘하게 나온다.

 

시작일과 종료일, 그리고 총일수를 확인해 본다.

print(f"시작일: {min(off_df_ct['DATE'])}") 
print(f"종료일: {max(off_df_ct['DATE'])}")
print(f"일수: {off_df_ct['DATE'].nunique()}일")

▶ 731일로 시각화하기엔 너무 많기 때문에, 특정 단위 기간 (ex. 30일, 1개월 등)으로 단위 기간을 조절해줄 필요가 있다.

 

앞서 날짜의 데이터 타입을 확인해본 결과 object로 되어 있으므로, 판다스의 to_datetime을 통해 날짜로 형변환을 해주고, 날짜를 1개월 단위로 쪼갠다.

# 날짜를 datetime으로 형변환
off_df_ct['DATE'] = pd.to_datetime(off_df_ct['DATE'])

# 날짜를 1개월 단위로 집계 (예: 방문자수와 참여자수의 합계)
off_df_1m = off_df_ct.resample('1M', on='DATE').sum().reset_index()

# 시각화
labels = ['VISITORS', 'PART']

fig = plt.figure()
for label in labels:
    x = off_df_1m['DATE']
    y = off_df_1m[label]
    sns.lineplot(x=x, y=y, label=label)

plt.legend()
plt.title('월간 단위 방문자수와 참여자수')  # 제목 추가
plt.xlabel('날짜')  # x축 라벨 추가
plt.ylabel('수')  # y축 라벨 추가
plt.xticks(rotation=45)  # x축 날짜 라벨을 기울여서 가독성 향상
plt.show()  # 그래프 출력

▶ 선차트를 따로 따로 보여지게 하는 것이 좋을 거 같다. (후에 Streamlit 에서 구현 시에는 나눠지도록 작업 예정)


2. 월간 지역별 방문자수 시각화

월간 지역별 방문자수 집계를 위해 groupby를 사용하여 'CITY'별로 데이터를 그룹화하고, pd.Grouper를 이용해 날짜를 월 단위로 집계한다. 각 도시별로 월간 방문자 수를 합산하여 monthly_visitors라는 새로운 데이터프레임을 만든다.

# 'DATE'를 월 단위로 그룹화하고 각 도시별 방문자 수를 합산
monthly_visitors = off_df_ct.groupby(['CITY', pd.Grouper(key='DATE', freq='M')])['VISITORS'].sum().reset_index()

# 시각화
fig = plt.figure(figsize=(12,9))

# Seaborn으로 라인 플롯 생성 - hue를 CITY로 지정하여 지역별로 색상을 다르게 설정
sns.lineplot(data=monthly_visitors, x='DATE', y='VISITORS', hue='CITY')

plt.legend(loc='upper center', ncol=10, bbox_to_anchor=(0.5, 1))
plt.title('월간 지역별 방문자수')  # 제목 추가
plt.xlabel('날짜')  # x축 라벨 추가
plt.ylabel('수')  # y축 라벨 추가
plt.xticks(rotation=45)  # x축 날짜 라벨을 기울여서 가독성 향상
plt.show()  # 그래프 출력


3. 월간 지역별 참여자수 시각화

같은 방식으로 월간 지역별 참여자수도 시각화해 본다.

 


4. 지역별 방문자수, 참여자수 누적 막대그래프 그리기

지역별로 방문자수와 참여자수를 누적 막대그래프로 시각화해 본다.

이를 위해 지역별로 방문자수와 참여자수가 집계된 데이터를 각각 만든다. (그대로 불러올 경우 로딩시간이 소요되기 때문)

 

그리고 누적 막대그래프를 위해 두 데이터를 병합시켜준다.

# 데이터 집계
vis_ct = off_df_ct.groupby(['CITY'])['VISITORS'].sum().reset_index()
part_ct = off_df_ct.groupby(['CITY'])['PART'].sum().reset_index()

# 데이터프레임 병합
combined_ct = vis_ct.merge(part_ct, on='CITY', suffixes=('_VISITORS', '_PART'))

# 바 그래프 생성
plt.figure(figsize=(10, 5))

# 방문자수와 참여자수를 나란히 그리기 위해 barplot 사용.
sns.barplot(data=combined_ct, x='CITY', y='VISITORS', color='r', label='VISITORS')
sns.barplot(data=combined_ct, x='CITY', y='PART', color='b', label='PART', alpha=0.5)

# 범례 설정
plt.legend(loc='upper center', ncol=2, bbox_to_anchor=(0.5, 1))

# 그래프 꾸미기
plt.title('지역별 방문자수 및 참여자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('수')  # y축 라벨 추가
plt.show()  # 그래프 출력

 

물론, 따로따로 시각화해도 된다.

단, 데이터가 균등해서 시각화했을 때 별 차이가 없으므로, y축 눈금의 범위를 변경해서 좀 더 차이가 뚜렷해 보이도록 바꿔준다.

또한, barplot에 palette 매개변수를 줘서 색상을 좀 더 다양하게 나오도록 한다.

 

먼저 지역별 방문자수

# 데이터 집계
vis_ct = off_df_ct.groupby(['CITY'])['VISITORS'].sum().reset_index()

# 바 그래프 생성
plt.figure(figsize=(10, 5))

# barplot 사용.
sns.barplot(data=vis_ct, x='CITY', y='VISITORS', palette='Set3')

# 그래프 꾸미기
plt.title('지역별 방문자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('수')  # y축 라벨 추가
plt.ylim(50000, 70000)
plt.show()  # 그래프 출력

그리고 지역별 참여자수

# 데이터 집계
part_ct = off_df_ct.groupby(['CITY'])['PART'].sum().reset_index()

# 바 그래프 생성
plt.figure(figsize=(10, 5))

# barplot 사용.
sns.barplot(data=part_ct, x='CITY', y='PART', palette='Set2')

# 그래프 꾸미기
plt.title('지역별 참여자수')  # 제목 추가
plt.xlabel('지역')  # x축 라벨 추가
plt.ylabel('수')  # y축 라벨 추가
plt.ylim(10000, 30000)
plt.show()  # 그래프 출력

 


5. 파이차트: 지역별 참여자수, 지역별 방문자수 각각 그려보기

 

- 지역별 방문자 비율 

# 데이터 집계
vis_ct = off_df_ct.groupby(['CITY'])['VISITORS'].sum().reset_index()

labels = vis_ct['CITY'].unique()

plt.pie(data = vis_ct, x='VISITORS', labels=labels, autopct='%.1f%%',startangle=260)
plt.title("지역별 방문자 비율")
plt.show()

 

- 지역별 참여율

: 지역별 참여율은 방문자 비율에 여러 옵션들을 추가하여 심미성을 추가해 준다.

  • explode: 데이터 간격 띄우기
  • color: Seaborn의 palette 옵션에서 특정 색 모임 가져오기
  • shadow: 각 조각마다 그림자 효과 추가하기
# 데이터 집계
part_ct = off_df_ct.groupby(['CITY'])['PART'].sum().reset_index()

labels = part_ct['CITY'].unique()
explode = [0.1 for _ in range(len(labels))]  # 모든 섹터를 약간 부풀리기

# 색상 팔레트 설정
colors = sns.color_palette("Set3", len(labels))

plt.pie(data = part_ct, x='PART', labels=labels, autopct='%.1f%%',startangle=260, 
         colors=colors, explode=explode, shadow=True)
plt.title("지역별 참여율")
plt.show()

 

 

다음에는 오프라인 캠페인 관련 데이터를 가지고 시각화를 진행해 본다.


다음 내용

 

[파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 3

이전 내용 [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 2이전 내용  [파이썬] 프로젝트 : 대시보드 웹 페이지 구축하기 - 1프로젝트 개요 2차 프로젝트를 시작하게 되었다.이번에 해야할

puppy-foot-it.tistory.com

 

 

728x90
반응형