오도원입니다.

건강과 행복을 위하여

PNU DSC/파이썬 데이터 분석

04-1. 대중교통 공공데이터

오도원공육사 2020. 5. 29. 02:33
반응형

1. 대중교통 데이터 내려받기

https://pay.tmoney.co.kr/index.dev

 

티머니 카드&페이

티머니카드, 어린이/청소년할인, T마일리지적립, 소득공제, 유통/교통/모바일결제, 고속/시외버스예매

pay.tmoney.co.kr

1. 이용안내 선택

 

2. 대중교통 통계자료 선택

3. 2020년 4월 교통카드 통계자료 선택

 

4. 월간 교통카드 통계자료 다운로드

 

이제 다운받은 엑셀 파일을 살펴보자.

  • 버스정류장별 이용현황
  • 지하철 노선별 역별 이용현황
  • 지하철 유무임별 이용현황
  • 지하철 시간대별 이용현황

이렇게 4가지의 통계자료를 볼 수 있다. 가장 먼저 활용할 데이터는 '지하철 유무임별 이용현황' 데이터이다.

 

2. 지하철 유무임별 이용현황 데이터 정제하기

지하철 유무임별 이용현황 시트를 선택하고 'subwayfee.csv'로 수정하고, 파일형식을 CSV로 선택한 후 저장한다.

 

데이터를 살펴보면 숫자에 콤마(,)가 포함되어 있으므로 '찾기 및 바꾸기' 기능으로 ,를 모두 없앤다.

다음과 같이 파이썬의 replace함수를 이용할 수도 있다.

row[4] = int(row[4].replace(',', ''))

 

또한, '작업일시' 데이터가 있는 열을 삭제하겠다.

이제 데이터가 제대로 정제되었는지를 확인해보자.

import csv
f = open('subwayfee.csv')
data = csv.reader(f)

for row in data:
    print(row)

0번 줄(행)이 헤더(header)인 것을 알 수 있고, 4번부터 7번 인덱스열까지의 데이터가 문자열로 되어있기 때문에, int로 바꿔서 처리해야한다는 것을 알 수 있다. 반복문을 이용해서 정수(int)로 바꿔주자.

 

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    header = next(data)
    
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',',''))
        print(row)

 

3. 유임 승차 비율이 가장 높은 역은 어디일까

먼저 유임 승차 비율을 어떻게 구할지를 정해야한다.

 

여기서는 유임승차인원과 무임승차인원을 비교해서 구한다.

  • rate = 유임승차인원 / 무임승차인원

1. 데이터를 읽어온다.

2. 모든 역의 데이터를 바탕으로 각 역의 비율(rate)를 계산한다.

3. 비율이 가장 높은 역을 찾는다.

4. 비율이 가장 높은 역이 어딘지, 그 비율이 얼마인지 출력한다.

 

(1)번은 이미 구현했기 때문에 (2), (3)을 구현해보자. 각 역의 비율데이터를 저장할 rate 변수와 rate의 최대값을 저장할 mx 변수를 0으로 초기화한다.

 

유임 승차 인원(row[4])를 무임 승차 인원(row[6])로 나눈 rate값을 계산하고 rate값이 최대일 때를 찾는다.

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    mx = 0
    rate = 0
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',', ''))
        rate = row[4] / row[6]
        if rate > mx:
            mx = rate
print(mx)

에러가 발생한다. 0으로 나눴다는 에러가 발생했다. row[6]에 값이 0인 지역이 존재하기 때문이다. 한번 row[6]가 0인 역들을 출력해보자.

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    for row in data:
        if row[6] == '0':
            print(row)

 

row[6]에 대한 예외 처리(0이 아닌 경우)를 수행하고, rate가 가장 높은 역이 어디인지 얼마나 비율이 높은지 확인하자.

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    rate = 0
    mx = 0
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',',''))
        if row[6] != 0: # 만약 row[6](무임 승차 인원)값이 0이 아니라면
            rate = row[4] / row[6]
            if rate > mx: # rate 값이 mx보다 크다면
                mx = rate # mx값을 rate로 갱신
                print(row, round(rate, 2)) # 갱신된 값 출력

4. 유임 승차 비율 구하는 방법 바꿔서 구해보기

이번에는 유임 승차 비율을 전체 유무임 승차 인원 중 유임 승차 인원의 수로 구해보겠다.

  • rate = 유임 승차 인원 / 전체(유임 + 무임) 인원

유무임 승차 인원을 합해서 100,000명 이상인 경우만 찾는 것으로 했다.

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    rate = 0
    mx = 0
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',',''))
        if row[6] != 0 and (row[4] + row[6]) > 100000:
            rate = row[4] / (row[4] + row[6])
            if rate > mx:
                mx = rate
                print(row, round(rate, 2))

실행 결과를 살펴보면, '한양대', '강남', '홍대입구'와 같이 대학 근처 역이나 강남역, 서울역같은 사람이 많이 다니는 곳의 유임 승차 비율이 높다는 것을 알 수 있다.

 

다음 코드를 추가해서 출력하면 다음과 같다.

if rate > 0.9:
    print(row, round(rate, 2))

'마곡나루'와 같이 낯선 역 이름이라도 젊은 사람들이 많이 모이는 곳이라는 것을 알 수 있다.

 

이제 유임 승차 비율이 가장 높은 역에 대한 저보를 보기 쉽게 출력해보겠다. 먼저 비율이 가장 높은 역이 어디인지 저장할 mx_station 변수를 빈 문자열('')로 초기화한다. 그리고 역이름(row[3])과 몇 호선(row[1])정보를 저장하고 출력해보자.

더보기
with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    
    rate = 0
    mx = 0
    mx_station = ''
    
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',',''))
        if row[6] != 0 and (row[4] + row[6]) > 100000:
            rate = row[4] / (row[4] + row[6])
            if rate > mx:
                mx = rate
                mx_station = row[3] + ' ' + row[1]

print(mx_station, round(mx*100, 2))                

20년 4월 기준으로 유임 승차 비율이 가장 높은 역은 '마곡나루'역 이라는 사실을 알 수 있다.

 

5. 유무임 승하차 인원이 가장 많은 역은 어디일까

이번에는 유무임을 통틀어 승하차 인원이 가장 많은 역이 어디인지 살펴보자. 비율이 아닌 인원이 가장 많은 역을 찾는 것이다.

 

따라서, 유임 승차, 유임 하차, 무임 승차, 무임 하차 이누언 이 가장 많은 역을 찾으면 되니깐 간단한 알고리즘을 생각할 수 있다.

 

1. 데이터를 읽어온다.

2. 모든 역의 데이터를 바탕으로 유임승차, 유임하차, 무임승차, 무임하차 인원이 가장 많은 역을 찾는다.

3. 각각의 인원이 가장 많은 역을 출력한다.

 

지금까지의 패턴과 유사하지만 이번에는 4가지 종류의 데이터(유임승차, 유임하차, 무임승차, 무임하차)를 알아보아야 한다. 따라서 인원수를 저장할 공간 4개와 역의 정보를 저장할 공간 4개가 추가로 필요하다.

 

유임 승차, 유임 하차, 무임 승차, 무임 하차데이터가 4번 인덱스부터 7번 인덱스까지 순서대로 저장되어있으므로 리스트와 반복문을 활용하면 될 것이다.

 

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    mx = [0] * 4
    mx_station = [''] * 4
    label = ['유임승차', '유임하차', '무임승차', '무임하차']
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',',''))
            if row[i] > mx[i-4]:
                mx[i-4] = row[i]
                mx_station[i-4] = row[3] + ' ' + row[1]

for i in range(4):
    print(label[i] + ' : ' + mx_station[i], mx[i])

6. 모든 역의 유무임 승하차 비율을 어떻게 될까

모든 역에 대한 유무임 승하차 비율을 알아보자. 이러한 유형의 데이터는 파이차트로 표현하는 것이 좋다. 

import csv
import matplotlib.pyplot as plt

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    label = ['유임승차', '유임하차', '무임승차', '무임하차']
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',', ''))
        plt.pie(row[4:8])
        plt.show()

해당 코드를 실행하면 엄청나게 많은 양의 파이 차트가 생성된다. 이 코드를 어떻게 보완하면 좋을까?

 

1. 어떤 역에 대한 차트인지 정보가 부족하다.

2. 비율을 수치로 정확하게 나타내면 좋다.

3. 색상을 좀 더 이쁘게 바꾸고 싶다.

 

따라서 역 이름을 제목으로 표시하고 각각의 비율과 레이블과 색상을 추가해보자.

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    label = ['유임승차', '유임하차', '무임승차', '무임하차']
    c = ['#14CCC0', '#389993', '#FF1C6A', '#CC14AF']
    plt.rc('font', family='Malgun Gothic')
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',', ''))
        plt.figure(dpi=300)
        plt.title(row[3] + ' ' + row[1])
        plt.pie(row[4:8], labels=label, colors=c, autopct='%1.f%%')
        plt.show()

마지막으로 시각화한 자료를 이미지 파일로 저장해보자. 그래프를 이미지로 저장하려면 savefig() 함수를 사용한다. 이때 이미지 파일의 이름과 형식을 지정할 수 있다. row[3]에는 역 이름, row[1]에는 노선 이름이 저장되어있다. 따라서 역이름과 노선이름으로 파일 제목을 생성하고, png 형식의 이미지 파일로 저장한다. 

 

따라서 row[3] + ' ' + row[1] + '.png' 형태의 이미지 파일 이름을 지정할 수 있다. 그러면 파일 이름이 '강남 2호선.png'형식으로 만들어질 것이다. 다음 코드를 추가한다.

plt.savefig(row[3] + ' ' + row[1] + '.png') # 이미지 파일로 저장
plt.show()

 

전체코드

with open('subwayfee.csv') as f:
    data = csv.reader(f)
    next(data)
    label = ['유임승차', '유임하차', '무임승차', '무임하차']
    c = ['#14CCC0', '#389993', '#FF1C6A', '#CC14AF']
    plt.rc('font', family='Malgun Gothic')
    for row in data:
        for i in range(4, 8):
            row[i] = int(row[i].replace(',', ''))
        plt.figure(dpi=300)
        plt.title(row[3] + ' ' + row[1])
        plt.pie(row[4:8], labels=label, colors=c, autopct='%1.f%%')
        plt.savefig('./유무임승하차/' + row[3]+' '+row[1]+'.png') # 파일들이 유무임승하차 폴더에 저장될 것이다.
        plt.show()

 

반응형