728x90
반응형

데이터 전처리 시각화

🐳 데이터 불러오기

### 라이브러리 정의하기
import pandas as pd

### 사용할 데이터 읽어오기
# 데이터프레임 변수명 : df_bus_card_tot
file_path = "./01_data/all/df_bus_card_tot.csv"
df_bus_card_tot = pd.read_csv(file_path)

print("갯수 : ", len(df_bus_card_tot))
df_bus_card_tot.head(1)

 

 

데이터 시각화

시각화의 목적?
직관적인 데이터 확인

 

🐳 시각화에 필요한 라이브러리

### 시각화 라이브러리
import matplotlib # 시각화 라이브러리를 쓰겠다!
import matplotlib.pyplot as plt # 차트나 그림이 들어있다
import seaborn as sns # 파스텔 색감

### 그래프 내에 한글이 포함된 경우 폰트 처리가 필요하다
# - 한글 꺠짐 방지를 위한 라이브러리
### 폰트 환결설정 라이브러리
from matplotlib import font_manager, rc

### 운영체제 확인을 위한 라이브러리
# import platform

plt.rc("font", family = "Malgun Gothic")

### 그래프 내에 마이너스(-) 표시 기호 적용하기
plt.rcParams["axes.unicode_minus"] = False

 

🐳 기준월 및 기준일자별 버스 이용량 시각화 분석

  • 사용할 컬럼 : 기준월, 기준일, 승객연령
  • 사용할 집계함수 : count
  • 이용량 집계를 위한 함수 : pivot_table()
    - 히트맵 시각화시 데이터 생성
  • 사용할 그래프 : 히트맵(hitmap)
    - 히트맵을 그리기 위한 데이터를 만들어야 하는데, 그 데이터를 만들어내는게 피벗테이블
df_pivot = df_bus_card_tot.pivot_table(index = "기준월",
                                       columns = "기준일",
                                       values = "승객연령",
                                       aggfunc = "count")

 

<데이터 count 집계하기>
- y축 : index
- x축 : columns
- 집계 : count(승객연령)

- 결측값 존재 : NaN

 

 

 

🐳 결측치(NaN) 처리하기

  • 결측치를 처리한 이유가 명확해야 한다.
    - 2월 결측치의 경우 2월이 28일 밖에 없어서 나머지 일에는 결측치가 나왔고 타당한 이유이기에 처리가 가능하다.
    - 3월 결측치의 경우 타당한 이유가 없이 결측치를 처리 할 수 없다. 이럴땐 데이터 제공자 측에 왜 데이터가 없는지 확인하고 타당한 이유 생성해야한다. 만약 버스시스템 오류로 인한 확인 불가라는 답변이 온다면 이유가 생성 됐다면 결측치를 0으로 처리하고 타당한 이유 작성하면 된다.
    - 0 으로 처리하지 않고 3월의 전체 평균을 삽입하거나 비어있는 값 전의 값과 후의 값의 평균을 넣거나 데이터를 아예 삭제하는 방법이 있다.
  • 모든 결측치(NaN)는 0으로 대체하기
df_pivot = df_pivot.fillna(0)
df_pivot

 

 

히트맵(heatmap) 시각화

🐳 기준일 및 기준일자별 버스 이용량 시각화 분석

### 그래프 전체 너비, 높이 설정
plt.figure(figsize=(20, 10))

### 그래프 제목 넣기
plt.title("기준월 및 기준일자별 버스 이용량 분석")

### 히트맵 그리기 : 히트맵은 seaborn 라이브러리에 존재한다
# - annot : False는 집계값 숨기기, True는 집계값 보이기
# - fmt : ".0f"는 소숫점 0자리까지 보이기
# - cmap : colormap, 컬러 색상그룹
sns.heatmap(df_pivot, annot=True, fmt=".0f", cmap="rocket_r")

### 그래프 출력
plt.show()

 

  • 그래프 해석
     - 1월 ~ 3월까지의 이용량을 분석한 결과 1월에 가장 많은 이용량을 나타내고 있으며, 2월에서 3월로 가면서 이용량이 점진적으로 줄어들고 있는 것으로 확인된다.
     - 1월 이용량이 가장 많은 이유는 포항시의 특성상 외부에서 관광객의 유입에 따라, 버스를 이용하는 사람들이 많을 것으로 예상된다.
     - 이에 따라, 포항시 관광객에 대한 데이터를 수집하여 해당 년월에 대한 데이터를 비교 분석해볼 필요성이 있다.

🐳 기준일 및 기준시간별 버스 이용량 시각화 분석

df_pivot = df_bus_card_tot.pivot_table(index = "기준일",
                                       columns = "기준시간",
                                       values = "승객연령",
                                       aggfunc = "count")
# 결측치 처리
df_pivot = df_pivot.fillna(0)

# 히트맵 그리기
plt.figure(figsize=(20, 10))

plt.title("기준일 및 기준시간별 버스 이용량 분석")

sns.heatmap(df_pivot, annot=True, fmt=".0f", cmap="YlGnBu")

plt.show()

  • 그래프 해석
    - 버스 이용량에 대한 분석결과, 일반적으로 출/퇴근 시간에 많아야 할 버스 이용량이 포항시의 경우 오후 시간대에 이용량이 밀집되어있다.
    - 특히, 오후1시와 3시에 높은 이용량을 나타내고 있다.
    - 이는 출/퇴근 시간에 자가 차량을 이용하는 사람이 많을 수도 있다는 예상을 할 수 있으며,
    인구 분포가 노령인구가 많기에 오후에 이용자가 많을 수도 있을 수 있다.
    - 따라서, 포항시 인구현황 데이터, 경제활동인구 분석을 통해 비교 분석이 가능할 것으로 예상된다.
    - 또한, 해당 이용량이 높은 시간대의 노선을 확인하여 특성 확인도 필요할 것으로 예상된다.

🐳 기준시간 및 분별 버스 이용량 시각화 분석

df_pivot = df_bus_card_tot.pivot_table(index = "기준시간",
                                       columns = "기준시간(분)",
                                       values = "승객연령",
                                       aggfunc = "count")
# 결측치 처리
df_pivot = df_pivot.fillna(0)

# 히트맵 그리기
plt.figure(figsize=(20, 10))

plt.title("기준시간 및 기준시간(분)별 버스 이용량 분석")

sns.heatmap(df_pivot, annot=True, fmt=".0f", cmap="coolwarm")

plt.show()

  • 그래프 해석
    - 출근 시간대의 버스이용량을  볼 때 오전 7시 55분 ~ 8시 10분 사이에 이용량이 많은 것으로 보인다.
    - 퇴근 시간대의 버스 이용량을 볼 때 오후 6시 ~ 6시 20분까지 이용량이 많은 것으로 보인다.
    - 특히 오후 3시 20분까지 버스 이용량이 매우 크게 나타나고 있다.
    - 오후 시간대 이용자에 대한 추가 확인이 필요할 것으로 보인다. 

🐳 기준일 및 시간별 버스내체류시간(분) 시각화 분석

df_pivot = df_bus_card_tot.pivot_table(index = "기준일",
                                       columns = "기준시간",
                                       values = "버스내체류시간(분)",
                                       aggfunc = "mean")
# 결측치 처리
df_pivot = df_pivot.fillna(0)

# 히트맵 그리기
plt.figure(figsize=(20, 10))

plt.title("기준일 및 시간별 버스내체류시간(분) 시각화 분석")

sns.heatmap(df_pivot, annot=True, fmt=".3f", cmap="BuPu")

plt.show()

  • 그래프 해석
     - 매월 1일에 장거리 이용자가 다소 분포하고 있으며 오전 5시부터 8시를 전후로 장거리 이용자가 증가하고 있다.
     - 오후 5시에 장거리 이용자가 매우 많게 나타난다. 이는 포항시 주변 상권(경제활동인구)의 출/퇴근 시간의 영향을 받을 수도 있을 것으로 예상된다.
     - 오후 7시 이후로는 장거리 이용자가 보편적으로 나타나고 있으며, 위에서 분석한 기준일 및 시간별 이용량 분석에서 확인한 바와 같이 7시 이후의 버스 이용량도 급격하게 줄어드는 것을 보아 저녁시간 버스 이용이 현저히 낮은것으로 보인다.
     - 장거리 이용자가 많은 시간대에 급행버스의 도입에 대한 추가 확인은 필요할 것으로 여겨진다.


막대그래프 시각화

🐳시간대 및 승객구별 버스내체류시간(분) 시각화

  • 필요한 데이터 추출
    - 기준시간, 승객연령, 버스내체류시간(분)
df_temp = pd.DataFrame()
df_temp["기준시간"] = df_bus_card_tot["기준시간"]
df_temp["승객구분"] = df_bus_card_tot["승객연령"]
df_temp["버스내체류시간"] = df_bus_card_tot["버스내체류시간(분)"]
df_temp


  • 승객 빈도 확인하기
df_temp["승객구분"].value_counts()


  • 그룹화 하기
  • 그룹화 후 head()
    - df_temp2.head(1)
    - groupby 이후의 head()의 역할 : 행단위로 조회하는게 아니라 그룹 단위로 조회한다.
    - groupby하고 head(1) 하면 각 그룹의 첫번째 값이 조회 된다.
# sum()
df_temp2 = df_temp.groupby(["기준시간", "승객구분"], as_index=False).sum()

# 내림차순 정렬
df_temp2 = df_temp2.sort_values(by=["버스내체류시간"], ascending=False)
df_temp2


  • 데이터의 행과 열을 교환하기
df_temp2.transpose()


  • 막대그래프 시각화 하기
fig = plt.figure(figsize=(25, 10))

plt.title("시간 및 승객구분별 버스내체류시간(분) 분석")

### hue : x축 및 y축을 기준으로 비교할 대상 컬럼 지정(범주형 데이터를 보통 사용)
sns.barplot(x="기준시간", y="버스내체류시간", hue="승객구분", data=df_temp2)

plt.show()

 

 

밀도그래프 시각화( histplot )

  • 2개의 그래프 조합

🐳시간대 및 승객구별 버스내체류시간(분) 시각화

plt.figure(figsize=(12, 4))
plt.title("시간 및 승객구분별 버스내체류시간(분) 분석")

sns.histplot(data = df_temp2,
            x = "기준시간",
             
            ### 사용할 막대의 최대 갯수
            bins = 30,
             
            ### 막대그래프에 밀도 선그리기            
            kde = True,
             
            ### 범주 데이터
            hue = "승객구분",
             
            ### 여러 범주를 하나의 막대에 표현하기
            multiple = "stack",
            
            ### 비율로 표시
            stat = "density",
             
            ### 막대 너비 : 0.6은 60% 축소한 너비 사이즈
            shrink = 0.6)

plt.show()

 

 

선그래프 시각화

🐳승차하정류장별 버스내체류시간(분) 상위 30건 시각화 분석

  • 구간(승차정류장 ~ 하차정류장) 까지의 버스내 체류시간을 이용하여 체류시간이 많은 구간을 확인하기
df_temp3 = pd.DataFrame()
df_temp3["버스내체류시간"] = df_bus_card_tot["버스내체류시간(분)"]
df_temp3["승하차정류장"] = df_bus_card_tot["승차정류장"] + "-->" + \
                         df_bus_card_tot["하차정류장"]
df_temp3


  • 구간별 그룹화 하기
### 구간(승차정류장 ~ 하차정류장)별 버스내체류시간(분) sum() 그룹화 하기
df_temp_gp = df_temp3.groupby(["승하차정류장"], as_index=False).sum()

### 내림차순 정렬
df_temp_gp = df_temp_gp.sort_values(by=["버스내체류시간"], ascending=False)

### 상위 30건 추출하기
df_temp_gp.head(30)


  • 선 그래프 그리기
plt.figure(figsize=(12, 4))
plt.title("승하차정류장별 버스내 체류시간 분석")

### 선그래프
plt.plot(df_temp3["승하차정류장"], df_temp3["버스내체류시간"])

### x축 및 y축 제목 넣기
plt.xlabel("승하창정류장")
plt.ylabel("버스내체류시간(분)")

### x축의 값의 기울기를 이용하여 조정하기
# - xticks() : x축을 컨트롤하는 함수
plt.xticks(rotation=90)

### 격자선 표시하기
plt.grid(True)

plt.show()

728x90
반응형

+ Recent posts