오늘 실습해볼 내용은 따릉이 데이터 분석 서울 열린데이터광장에서 다운 받을 수 있는 따릉이 데이터를 통해 사람들이 언제 많이 타는지(이용건수)와 한 번 대여하면 어느 정도의 시간을 대여하는지(이용시간) 등의 데이터 분석을 진행해보도록 하겠습니다.
위의 링크에 접속해 대여소명, 자전거번호, 대여일시, 반납일시, 이용시간 등의 데이터가 담긴 파일을 다운받습니다.
데이터 전처리
pandas 라이브러리로 데이터를 읽고 가공하는데 사용합니다.
matplotlib와 seaborn으로 다양한 그래프를 작성합니다.
마지막으로 folium을 이용하여 시각화 지도 그리기를 진행합니다.
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import folium
제공된 데이터는 총 6개로 bike_rent_1부터 6까지 있습니다.
6개로 나누어진 csv 파일을 읽어들여서 하나의 데이터프레임으로 합쳐줍니다.
csv 파일을 읽어서 데이터프레임으로 만든 후, bikes_temp라는 딕셔너리의 값에 할당합니다.
대여일시는 datetime 자료형으로 읽도록 parse_dates를 사용하여 지정된 열(column)을 날짜/시간(datetime) 형식으로 해석하고 변환합니다.
bikes_temp = {}
for i in range(6):
bikes_temp[i] = pd.read_csv('./bike_rent_{}.csv'.format(i+1),
encoding='cp949',
parse_dates=['대여일시'],
date_format='%Y-%m-%d %H:%M')
읽어들인 데이터프레임을 살펴보겠습니다.
bikes_temp[0].head()

마지막으로 concat 함수를 이용하여 데이터프레임을 연결합니다.
bike_temp에 있는 딕셔너리 데이터프레임들을 인덱스(행) 방향으로 연결하고 인덱스를 0부터 순서대로 지정하는 코드입니다.
bikes = pd.concat(bikes_temp, axis='index',ignore_index=True)
데이터프레임이 잘 형성되었는지 살펴봅시다.
bikes.info()

누락된 데이터가 없는지 검사합니다.
bikes.isnull().sum()

만든 bikes 데이터프레임에 시간 컬럼을 추가합니다. ‘대여일시’는 데이터타입이 datetime64입니다. 판다스 라이브러리에 있는 dt 액세서를 사용하여 날짜 데이터타입인 bikes[‘대여일시’]에서 ‘일자’, ‘요일’ , ’주말여부’, ‘시간대’ 를 추출할 수 있습니다. 이 값들을 이용하여 새로운 컬럼을 만듭니다.
요일 = ['월','화','수','목','금','토','일']
bikes['요일'] = bikes['대여일시'].dt.dayofweek.apply(lambda x: 요일[x])
bikes.head()
dayofweek는 요일에 따라 월~일까지 0~6의 숫자를 순서대로 매칭하여 출력해줍니다.
그리고 apply 함수를 통해 데이터프레임 전체에 함수를 적용하게 해주는데 lambda 함수를 이용하여 입력되는 x의 값에 요일[x] 값들이 차례로 출력되게끔 코딩을 해줍니다.

다음으로 앞서만든 bikes 데이터프레임에 대여소 위치정보가 있는 파일을 읽어들여 합쳐주는 과정을 진행해보겠습니다.
이를 위해 해당 파일을 읽어들이고 bike_shop이라는 데이터프레임을 생성합니다. 이때 사용하는 파일이 csv가 아닌 xlsx이므로 pd.read_excel을 사용합니다.
bike_shop = pd.read_excel('./공공자전거 대여소 정보_201905.xlsx')
bike_shop.head()

위의 데이터에서 필요한 컬럼을 추출합니다.
bike_columns = bike_shop[['구분','대여소번호','대여소명','위도','경도']]
bike_columns.head(5)

이제 bikes 데이터프레임과 bike_columns 데이터프레임을 merge 함수를 이용하여 합칩니다.
bikes = pd.merge(bikes, bike_columns, left_on='대여 대여소번호', right_on='대여소번호')
bikes.head(5)
병합은 bikes의 '대여 대여소번호' 값과 bike_columns의 '대여소번호' 값이 일치할 때 수행되도록 코드를 작성해주었습니다.

필요없는 컬럼을 삭제해줍니다.
bikes.drop(['대여소번호', '대여소명'], axis='columns', inplace=True)
bikes.head(5)

컬럼의 이름을 변경해줍니다.
bikes.rename(columns={'구분':'대여구','위도':'대여소 위도','경도':'대여소 경도'}, inplace=True)
bikes.head(5)

추가적으로 개인이 조사하고 싶은 데이터가 있다면 더 추가해도 좋습니다.
일자별 데이터를 조사할 수 있도록 추가해보겠습니다.
bikes['일자'] = bikes['대여일시'].dt.day
bikes.head()
Pandas에서는 .dt 접근자(accessor)를 통해 날짜/시간 정보를 쉽게 추출할 수 있습니다.
| 속성 | 추출하는 정보 | 예시 |
| .dt.day | 일자 (Day of Month) | 1 ~ 31 |
| .dt.year | 연도 (Year) | 2023 |
| .dt.month | 월 (Month) | 1 ~ 12 |
| .dt.hour | 시 (Hour) | 0 ~ 23 |
| .dt.minute | 분 (Minute) | 0 ~ 59 |
| .dt.dayofweek | 요일 인덱스 (Day of Week) | 0 (월) ~ 6 (일) |
| .dt.day_name() | 요일 이름 (Day Name) | '월요일', 'Tuesday' 등 |

대여 시간대에 따른 데이터도 추가합니다.
bikes['대여시간대'] = bikes['대여일시'].dt.hour
bikes.head()
8시 49분에 빌렸다면 8로 표시됩니다.

마지막으로 주말과 평일을 구분해주는 데이터를 추가해봅시다.
bikes['주말구분'] = bikes['대여일시'].dt.dayofweek.apply(lambda x: '주말' if x in [5,6] else '평일')
bikes.head()

데이터 시각화
이제 seaborn 라이브러리를 사용하여 sns.countplot 내부에서 각각의 요일에 해당하는 자전거번호를 카운트해서 그래프의x축에는 요일을 표시하고,카운트 한 자전거 번호 개수를 y축으로 하여 막대그래프로 표현한다.
sns.countplot(data=bikes, x='요일', order=['월','화','수','목','금','토','일'])

대여 시간대에 따른 대여 수 입니다.
sns.countplot(x='대여시간대', data=bikes)

이번에는 대여 시간대와 요일별로 자전거 이용건수를 구해보자.
hourly_dayofweek_ride = bikes.pivot_table(index='대여시간대', columns='요일', values='자전거번호', aggfunc='count')
hourly_dayofweek_ride.plot(kind='line',title = '대여시간대 x 요일 이용건수', figsize=(15,4))
해당 분석을 위해 사용한 pivot_table() 함수는 특정 컬럼을 인덱스와 컬럼으로 재구조화해서 집계함수를 사용해줍니다.
index(행)으로 사용할 '대여시간대'와 columns(열)로 사용할 '요일' 그리고 집계할 값인 자전거번호와 aggfunc에는 집계함수로 count를 지정해줍니다.

동일한 데이터를 heatmap을 사용하여 표현해봅시다.
plt.figure(figsize=(10,8))
sns.heatmap(hourly_dayofweek_ride, annot=True, fmt='d')

'Basic Data Analysis' 카테고리의 다른 글
| 데이터 문해력 (1) | 2026.02.11 |
|---|---|
| Python pandas 시계열 데이터 전처리 (0) | 2025.09.30 |
| Python Pandas를 활용한 데이터 분석 실습 (0) | 2025.09.26 |
| Python Pandas (0) | 2025.09.25 |