데이터

[데이터 분석] 교통데이터 수집/가공

멈머이 2023. 11. 30. 01:21
728x90

* 데이터 출처

<포항시 BIS 교통카드 사용내역>
 - URL : 국가교통 데이터 오픈마켓

 

 

1. 데이터 수집

import pandas as pd

파이썬에서 데이터를 다룰 때는 항상 pandas 라이브러리를 정의해 준다.

 

 

 

 

데이터가 폴더만 80개가 있다.

하지만 폴더 내부의 파일명은 동일하다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

* 여러 개의 파일 데이터를 통합하는 경우에는

   한 개 파일을 기준으로 사용할 컬럼을 정의하여 가공 후 반복 처리하면 편하다.

 

 

* 0번 파일의 csv 데이터 읽어 들이기

# - 데이터프레임 이름 : df_bus_card_org
file_path = "./01_data/org/trfcard(0)/trfcard.csv"
df_bus_card_org = pd.read_csv(file_path)
df_bus_card_org.head(1)

 

 

* 결측치가 있는지 정보 확인하기

df_bus_card_org.info()

 

 

각각의 컬럼의 데이터 자료형 확인 가능.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* 기초통계확인 : 이상치데이터 확인하기

df_bus_card_org.describe()

 

논리적으로 이상한

값이 있나 없나

확인하기.

 

 

 

 

 

 

 

 

 

 

* 영문 컬럼명을 한글로 수정하기

### 메타정의서의 영문명, 한글명 컬럼 읽어들이기
# - 데이터프레임 이름 : df_bus_card_col_org
file_path = "./01_data/org/trfcard(0)/trfcard_columns.Xlsx"
df_bus_card_col_org = pd.read_excel(file_path,
                                  header = 2,
                                  usecols="B:C")
df_bus_card_col_org.head(1)

 

컬럼정의서의 파란 칸을 가져와서 영어 컬럼명을 한글로 바꾸어준다.

 

 


* 엑셀파일에서 컬럼명만 가져오는 방법

### 컬럼명의 이름을 매핑하여 변경하기 위해서는 컬럼정의 값을 key:value 딕셔너리 타입으로 정의해야함
# 예시 : {영문명 : 한글명, 영문명 : 한글명...}
### df_bus_card_col_org의 데이터를 딕셔너리로 변환하기

print(df_bus_card_col_org.iloc[0,0])
print(df_bus_card_col_org.iloc[0,1])
print(df_bus_card_col_org.iloc[1,0])
print(df_bus_card_col_org.iloc[1,1])

print("-------------------------------")

print(df_bus_card_col_org.loc[0,"컬럼명 (영문)"])
print(df_bus_card_col_org.loc[0,"컬럼명 (한글)"])

 

 

 - iloc[행, 열] : 인덱스 *번호*를 이용하는 방식

 - loc[행값, 열값] : 눈에 보이는 인덱스 *값을* 이용하는 방식

 

 


### df_bus_cart_col_org 데이터프레임을 딕셔너리로 변환
# - 딕셔너리 변수명 : df_bus_cart_col_new_dict
df_bus_card_col_new_dict = {}
for k,v in zip(df_bus_card_col_org.iloc[:, 0], df_bus_card_col_org.iloc[:, 1]) :
    print(k, v)
    df_bus_card_col_new_dict[k] = v

df_bus_card_col_new_dict

 

 

 - 영문명은 key로, 한글명은 value로 만들기
 예시) {'on_date' : '승차시각', 'off_date' : '하차시각'....}

           리스트 내 딕셔너리

 

 

 

 

 

 

 

* 컬럼명 변경하기

df_bus_card_org.rename(columns=df_bus_card_col_new_dict, inplace=True)
df_bus_card_org.head(1)

다른 방법 => df_bus_card_org = df_bus_card_org.rename(columns=df_bus_card_col_new_dict)

                      변경된 컬럼이름은 다시 자기 자신에게 담는 방법.


2. 데이터 가공

데이터를 가공하기 위해서는 우선 분석목적을 세운 뒤 그 목적에 맞게 데이터를 가공해 나가야 한다.

 

<분석 주제>
 - 대주제 : 포항시 버스 이용량 분석
 - 소주제
    (버스 이용량 분석)
    * 기준월 및 기분일자별 버스 이용량 분석 비교
    * 기준일 및 시간대별 버스 이용량 분석 비교
    * 기준시간 및 시간(분) 별 버스 이용량 분석 비교
    
    (버스 내 체류시간 분석)
    * 기준월 및 기준일자별 버스 체류시간 분석 비교
    * 기준일 및 시간대별 버스 체류시간 분석 비교
    * 기준시간 및 시간(분)별 버스 체류시간 분석 비교

    * 승하차 정류장 구간별 버스 내 체류시간
     - 체류시간(분) 상위 30건 분석비교

 

 

* 승차시각과 하차시각 데이터 타입을 문자열로 변환하기

### 데이터 프레임 복제하기
df_bus_card_kor = df_bus_card_org.copy()

원본데이터의 구조를 해치지 않기 위해 데이터를 복사해서 사용.

df_bus_card_kor = df_bus_card_kor.astype({"승차시각" : "str",
                                          "하차시각" : "str" })

df_bus_card_kor.info()

 

 

분석하려는 주제의 대부분이 시간, 날짜 기준이기 때문에 날짜타입으로 바꾸어주기 위해 문자열 타입으로 변환해 준다.

 - ascopy() : 데이터 형변환 함수

 

 

 

* 분석에 필요한 컬럼 추가하기

우선 분석 시 필요한 컬럼들만 가져온 뒤 그 데이터를 가공하여 컬럼에 추가해 준다.

df_bus_card = df_bus_card_kor[["승차시각", "하차시각", "승객연령", "환승여부",
					"추가운임여부", "승차정류장", "하차정류장"]].copy()

df_bus_card.head()

 

* 승차시각, 하차시각을 날짜타입으로 변경하기

df_bus_card["승차시각"] = pd.to_datetime(df_bus_card_kor.loc[:, "승차시각"])
df_bus_card["하차시각"] = pd.to_datetime(df_bus_card_kor.loc[:, "하차시각"])
df_bus_card.info()

 

* 버스 내 체류시간(분단위) 컬럼만들기

### 체휴시간(분) 계산 및 컬럼생성
df_bus_card["버스내채류시간(분)"] = round((df_bus_card["하차시각"] - df_bus_card["승차시각"]).dt.total_seconds()/60, 2)
df_bus_card

* 체류시간 = (하차시각 - 승차시각) / 60초 를 소수점 셋째 자리에서 반올림.

 

 

* 기준연도, 기준월, 기준일, 기준시간, 기준시간(분) 컬럼생성하기

# - 기준년도
df_bus_card["기준년도"] = df_bus_card["승차시각"].dt.year
# - 기준월
df_bus_card["기준월"] = df_bus_card["승차시각"].dt.month
# - 기준일
df_bus_card["기준일"] = df_bus_card["승차시각"].dt.day
# - 기준시간
df_bus_card["기준시간"] = df_bus_card["승차시각"].dt.hour
# - 기준시간(분)
df_bus_card["기준시간(분)"] = df_bus_card["승차시각"].dt.minute

df_bus_card

여기까지 파일 1개를 가공해 봤다. 

이제 반복문을 만들어 80개의 파일을 통합해 보자.


3. 전체파일 통합하기 

   - 위에서 한건 샘플 프로세스를 이용하여 전체파일 통합하기

from datetime import datetime

 - 통합되는 데이터가 많다보니 통합에 시간이 걸린다. 얼마나 시간이 걸리는지 보기 위한 라이브러리.

### 통합시작시간
start_date = datetime.today().strftime("%Y-%m-%d %H-%M-%S")

df_bus_card_tot = pd.DataFrame()
#df_bus_card_tot

### 0~79까지 폴더에 접근하기 위한 반복수행
for i in range(0, 80,1):
    file_path = f"./01_data/org/trfcard({i})/trfcard.csv"   # 포멧방식
    df_bus_card_org = pd.read_csv(file_path)
   # print(i, " / ", len(df_bus_card_org))

    # 메타정의서
    file_path = f"./01_data/org/trfcard({i})/trfcard_columns.Xlsx"
    df_bus_card_col_org = pd.read_excel(file_path,
                                      header = 2,
                                      usecols="B:C")
    #print(df_bus_card_col_org)
    #print(i, " / ", len(df_bus_card_col_org))

    
    ### df_bus_cart_col_org 데이터프레임을 딕셔너리로 변환

    df_bus_card_col_new_dict = {}
    for k,v in zip(df_bus_card_col_org.iloc[:, 0], df_bus_card_col_org.iloc[:, 1]) :
        df_bus_card_col_new_dict[k] = v


    df_bus_card_org.rename(columns=df_bus_card_col_new_dict, inplace=True)

    
    ### 데이터 프레임 복제하기
    df_bus_card_kor = df_bus_card_org.copy()
    
    ### 승차시각과 하차시각 데이터 타입을 문자열로 변환하기
    # - ascopy() : 데이터 형변환 함수
    df_bus_card_kor = df_bus_card_kor.astype({"승차시각" : "str",
                                              "하차시각" : "str" })

    ### 분석에 필요한 컬럼 추가하기
    df_bus_card = df_bus_card_kor[["승차시각", "하차시각", "승객연령", "환승여부", "추가운임여부", "승차정류장", "하차정류장"]].copy()


    ### 승차시각, 하차시각을 날짜타입으로 변경하기
    df_bus_card["승차시각"] = pd.to_datetime(df_bus_card_kor.loc[:, "승차시각"])
    df_bus_card["하차시각"] = pd.to_datetime(df_bus_card_kor.loc[:, "하차시각"])


    ### 체휴시간(분) 계산 및 컬럼생성
    df_bus_card["버스내채류시간(분)"] = round((df_bus_card["하차시각"] - df_bus_card["승차시각"]).dt.total_seconds()/60, 2)

    ### 기준년도, 기준월, 기준일, 기준시간, 기준시간(분) 컬럼생성하기
    # - 기준년도
    df_bus_card["기준년도"] = df_bus_card["승차시각"].dt.year
    # - 기준월
    df_bus_card["기준월"] = df_bus_card["승차시각"].dt.month
    # - 기준일
    df_bus_card["기준일"] = df_bus_card["승차시각"].dt.day
    # - 기준시간
    df_bus_card["기준시간"] = df_bus_card["승차시각"].dt.hour
    # - 기준시간(분)
    df_bus_card["기준시간(분)"] = df_bus_card["승차시각"].dt.minute

#    print(f"{i} / {len(df_bus_card)}")

    df_bus_card_tot = pd.concat([df_bus_card_tot, df_bus_card], axis=0, ignore_index=True)

### 통합 종료시간
end_date = datetime.today().strftime("%Y-%m-%d %H-%M-%S")


print(f"전체실행시간 ==> {start_date}~{end_date}")
print(f"df_bus_card_tot ==> {len(df_bus_card_tot)}")


4. 통합 데이터프레임 저장시키기

 - 저장 파일 위치 : all 폴더
 - 저장 파일 명 : 데이터프레임변수명과 동일하게
 -  확장자 : csv

save_path = "./01_data/all/df_bus_card_tot.csv"
df_bus_card_tot.to_csv(save_path, index=False)

 

 

최종적으로 모든 파일이 통합된 데이터프레임을 csv 파일로 저장했다.

728x90