카테고리 없음

기초 프로젝트_DAY1_데이터 전처리

iron-min 2025. 10. 13. 21:14

1. 프로젝트 목표 세우기

우선 조에서  '[차량] 친환경 차량 성능 데이터 분석' 이라는 데이터를 선택하게 되었습니다.

조원들끼리 희망하는 분야랑 연관이 많기도 했고 데이터가 깔끔하게 처리되어있어서 전처리하고 시각화하는 것이 용의할것 같았습니다.

 

처리해야하는 데이터

 

우선 목표를 세우기 위해 주어진 배경을 살펴보았습니다.

에코 모빌리티의 주요 배경
  • 전 세계적인 탄소 배출량 감축 목표를 달성하기 위해 자동차 산업은 중요한 혁신 분야로 부상하고 있습니다.
  • 기존의 내연기관 차량은 주요한 배출원이며, 전기차(EV) 및 하이브리드 차량의 시장 점유율 확대가 필요한 상황입니다.
  • 친환경 차량의 개발과 보급이 중요한 이슈로 떠오른 만큼, 연비/이산화탄소 배출량 등 차량의 성능 데이터를 활용한 효율적인 분석 및 친환경 차량 개발을 위한 의사결정이 필수적입니다.
🚗  에코모빌리티의 데이터 분석가인 당신은 ‘친환경 차량 성능 분석 프로젝트’를 담당하게 되었어요.
🚗 프로젝트 요청사항은 아래와 같아요.
  • 차량 데이터를 탐색하여 연비와 배출량에 영향을 미치는 주요 요인을 시각적으로 표현해주세요.
  • 엔진 크기, 실린더 수, 연료 유형 등 주요 변수와 연비/배출량 간의 관계를 분석하고, 효율적인 차량 개발과 정책 수립을 위한 인사이트를 도출해주세요.

 

해당 배경으로 토의한 프로젝트 목표입니다.

  • 차종별 탄소배출 분석
    • 차종별 주행간 탄소배출량 비교
    • 차 엔진별 탄소 배출량 유의성 분석
    • 탄소배출량 저감에 효과적인 모델 10개, 비효과적인 모델 10개 선정 및 소개
      • 탄소배출량 저감에 기여한 기업 선정
  • 차종별 탄소배출 감축 전략 수립
    • 차종별 탄소배출량 시각화
      • 주요 기능
        • 차종별 연비와 배출량 상관계수 분석
        • 연료별 비교
        • 제조사별 평균 배출량
      • 목표
        • 차종별 탄소배출 저감 차종과 엔진등을 분석해서 기업에 대해 감축 전략을 컨설팅 한다.
        • 차량 연비와 배출량 사이의 관계를 검증하고 이를 바탕으로 친환경 전략을 제안
        • 탄소배출량 저감에 기여한 우수기업 선출

 

2. 전처리 계획 세우기

우선 전처리 계획을 세우기 위해 코딩을 통해 데이터를 확인해보았습니다.

1) 대소문자 구분의 문제로 중복되는 value가 존재

2) 현존하지 않는 기업의 차종이 존재

3) 데이터에 영향을 미치는 특수목적 차종이 존재

 

그래서 이러한 것들을 제거하기 위해 다음과 같이 계획하였습니다.

 

  • 데이터 전처리 계획
    • 현재 존재하지 않는 기업 데이터 전처리
      • ‘DAEWOO’ 를 ‘CHEVROLET’로 변경
      • 사라진 기업 삭제 : 'OLDSMOBILE’,‘PLYMOUTH’,’PONTIAC’,’SATURN’,’SCION’,’SRT’,’SAAB’
    • 사용하지 않는 컬럼 데이터 삭제
      • FUEL CONSUMPTION, HWY (L/100 km), TRANSMISSION
    • 단종모델 제거
      • 우수 모델 또는 미흡 모델에 단종모델이 포함될 경우 제거
    • 똑같은 차종 결합
      • VAN - PASSENGER → Van: Passenger 로 통합
      • STATION WAGON - SMALL → Station wagon : Small 로 통합
      • PICKUP TRUCK - STANKARD → Pickup truck: standard
      • SUV, SUV - STANDARD → SUV: Standard
      • MINIVAN → Minivan
      • FULL-SIZE → Full-size
      • MID-SIZE → Mid-size
      • SUV - SMALL → SUV: Small
      • STATION WAGON - MID-SIZE → Station wagon: Mid-size
      • STATION WAGON - SMALL → Station wagon: Small
      • SUBCOMPACT → Subcompact
      • COMPACT → Compact
      • MINICOMPACT → Minicompact
    • 특수목적 차종 제거
      • Special purpose vehicle, SPECIAL PURPOSE VEHICLE 제거
      • TWO-SEATER, Two-seater 제거

 

3. 전처리 실시

전처리에 오류가 있는지 서로간 확인하기 위해 저 포함 총 2명이 전처리를 하고 두 데이터를 비교해가며 전처리에 문제가 없는지 확인하기로 하였습니다.

 

저는 아래와 같이 데이터를 전처리 하였고

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from koreanize_matplotlib import koreanize_matplotlib as km_func

Fuel_Consumption = pd.read_csv(r'C:Fuel_Consumption_2000-2022.csv')
Fuel_Consumption = pd.DataFrame(Fuel_Consumption)

### 사라진 기업 삭제 ###
Fuel_Consumption_del_MAKE = Fuel_Consumption[
    (Fuel_Consumption['MAKE'] != 'PLYMOUTH') &
    (Fuel_Consumption['MAKE'] != 'PONTIAC') &
    (Fuel_Consumption['MAKE'] != 'SATURN') &
    (Fuel_Consumption['MAKE'] != 'SCION') &
    (Fuel_Consumption['MAKE'] != 'SRT') &
    (Fuel_Consumption['MAKE'] != 'SAAB') &
    (Fuel_Consumption['MAKE'] != 'OLDSMOBILE')
].copy()

### 대우를 쉐보레로 변경
Fuel_Consumption_del_MAKE['MAKE'] = Fuel_Consumption_del_MAKE['MAKE'].replace('DAEWOO','CHEVROLET')

### 사용하지 않는 컬럼 삭제
Fuel_Consumption_clean_column = Fuel_Consumption_del_MAKE.drop(['FUEL CONSUMPTION','HWY (L/100 km)','TRANSMISSION'],axis=1)

### 똑같은 차종 결합

Fuel_Consumption_replace_MODEL = Fuel_Consumption_clean_column.copy()

Fuel_Consumption_replace_MODEL['VEHICLE CLASS'] = (
    Fuel_Consumption_replace_MODEL['VEHICLE CLASS']
    .str.replace(':','-')  # 콜론을 하이픈으로 대체
    .str.capitalize()     # 첫 글자만 대문자로 변환
    .str.replace(' ','')          # 공백 제거
)

### 특수차종 제거
Fuel_Consumption_del_MODEL = Fuel_Consumption_replace_MODEL[
    (Fuel_Consumption_replace_MODEL['VEHICLE CLASS'] != 'Specialpurposevehicle') &
    (Fuel_Consumption_replace_MODEL['VEHICLE CLASS'] != 'Two-seater')
].copy()

 

 

조원 한분은 아래와 같이 전처리를 하였습니다.

# 대우를 쉐보레로 변경
df['MAKE'].replace('DAEWOO','CHEVROLET')
# 단종된 회사 삭제
drop_makes = ['OLDSMOBILE', 'PLYMOUTH', 'PONTIAC',
              'SAAB', 'SATURN', 'ISUZU', 'SUZUKI']
df = df[ df['MAKE'].isin(drop_makes) == False ]
# 사용하지 않는 컬럼 삭제
df_new1 = df.drop(columns = ['FUEL CONSUMPTION', 'HWY (L/100 km)', 'TRANSMISSION'])
df_new1.info()
# 같은 VEHICLE CLASS 문자 변경
df['VEHICLE CLASS'] = df['VEHICLE CLASS'].str.upper()
df['VEHICLE CLASS'] = df['VEHICLE CLASS'].str.replace(r"\s+", "", regex=True)   # 모든 공백 제거(스페이스 바 말고)
df['VEHICLE CLASS'] = df['VEHICLE CLASS'].str.replace(':','-')   # str 안쓰면 값 전체가 ':'가 아니면 안바뀜.
# 같은 MAKE 문자 변경
df['MAKE'] = df['MAKE'].str.strip()
df['MAKE'] = df['MAKE'].str.upper()
df.tail(30)
df['VEHICLE CLASS'].nunique()   # 17
df['VEHICLE CLASS'].value_counts()
# 소형,중형,대형,기타로 나누기
mapping = {
    #소형
    'MINICOMPACT' : 'SMALL',
    'SUBCOMPACT' : 'SMALL',
    'COMPACT' : 'SMALL',
    'SUV-SMALL' : 'SMALL',
    'STATIONWAGON-SMALL' : 'SMALL',
    'PICKUPTRUCK-SMALL' : 'SMALL',
    #중형
    'MID-SIZE' : 'MID',
    'SUV-STANDARD' : 'MID',
    'STATIONWAGON-MID-SIZE' : 'MID',
    'PICKUPTRUCK-STANDARD' : 'MID',
    'MINIVAN' : 'MID',
    #대형
    'FULL-SIZE' : 'LARGE',
    'SUV' : 'LARGE',
    'VAN-PASSENGER' : 'LARGE',
    'VAN-CARGO' : 'LARGE',
    #기타
    'SPECIALPURPOSEVEHICLE' : 'OTHER',
    'TWO-SEATER' : 'SMALL'
}
df['SIZE CLASS'] = df['VEHICLE CLASS'].map(mapping).fillna('OTHER')
df[df['SIZE CLASS'] == 'OTHER']
df.drop(df[ df['SIZE CLASS'] == 'OTHER'].index, inplace = True)
df.to_excel('my_dataset.xlsx', index = False)

 

그래서 비교해본 결과

 

제가 만든 코드는 이러한 장단점이 있고

  장점 단점
VEHICLE CLASS 처리 기존의 세부적인 차량 분류를 유지하여, 차량 종류별 미묘한 차이를 분석할 때 유리합니다. 세부 클래스가 많아지므로, 통계적 분석 시 범주의 수가 너무 많아져 해석이 어려울 수 있습니다
MAKE 제거 SCION 및 SRT와 같이 비교적 최근에 단종되거나 특수했던 브랜드를 제거하여 일관성 있는 메이커 목록을 만듭니다. ISUZU나 SUZUKI처럼 다른 코드에서 제거한 브랜드를 남겨두어, 분석 시 이들의 데이터가 포함될 수 있습니다.
데이터 형태 SIZE CLASS와 같은 추가적인 파생 변수가 없어 원본 데이터 구조에 더 가깝습니다. 대형/소형 등 직관적인 크기 비교 분석에는 부적합하며, 추가적인 매핑 작업이 필요합니다.

 

조원분이 만든 코드는 아래와 같은 장단점이 있었는데

  장점 단점
VEHICLE CLASS 처리 차량을 SMALL, MID, LARGE로 직관적으로 그룹화하여 크기별 연비 트렌드 분석이나 시각화에 매우 유리합니다. 세부적인 차량 정보를 단순화했기 때문에, 예를 들어 SUV-SMALL과 MINICOMPACT 간의 연비 차이와 같은 미세한 정보는 손실됩니다.
폐기된 기업 제거 모두 대문자로 변환하여 데이터 일관성 및 정렬에 유리합니다. 모든 차량 클래스가 대문자로 표시되어 가독성이 떨어질 수 있습니다.
데이터 형태 ISUZU와 SUZUKI를 포함하여 더 많은 단종 브랜드를 제거했습니다. SCION이나 SRT는 남겨두어 (만약 이들이 제거 대상이라면) 일관성이 부족할 수 있습니다.

 

전처리 완료된 데이터를 봤을때 데이터 분류가 같아서

SMALL, LARGE, MID로 분류된 2번째 전처리 데이터를 쓰기로 하였습니다.

 

4. 간단히 그래프화

이제 데이터를 분석하기전에 전처리한 데이터를 보기위해 간단한 그래프로 시각화를 하였습니다.

 

우선 연비와 탄소배출량, 연식, 엔진사이즈의 상관관계를 보기위해 다음과 같이 하였습니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from koreanize_matplotlib import koreanize_matplotlib as km_func

Fuel_Consumption = pd.read_csv(r'C:Fuel_Consumption_2000-2022.csv')
Fuel_Consumption = pd.DataFrame(Fuel_Consumption)

consumption_cols = ['YEAR','ENGINE SIZE','COMB (L/100 km)','EMISSIONS']
correlation_matrix = Fuel_Consumption[consumption_cols].corr()

COMB_corr = correlation_matrix['COMB (L/100 km)'].drop('COMB (L/100 km)')
COMB_corr_sorted = COMB_corr.reindex(COMB_corr.abs().sort_values(ascending=False).index)
categories = COMB_corr_sorted.index
values = list(COMB_corr_sorted.values)

plt.figure(figsize=(12, 8))
sns.barplot(y=categories, x=values, palette='viridis')

# 그래프 제목 및 라벨 설정
plt.title('Correlation with COMB', fontsize=16)
plt.xlabel('Correlation Coefficient', fontsize=12) # X축: 상관계수 값
plt.ylabel('Variables', fontsize=12)             # Y축: 변수 이름
plt.xlim(-1.0, 1.0) # X축 범위 설정
plt.axvline(0, color='grey', linestyle='--', linewidth=0.8)
plt.grid(axis='x', linestyle='--', alpha=0.7)

plt.tight_layout()
plt.show()

 

이런식으로 데이터가 나왔고 COMB는 엔진사이즈와 EMISSONS에 비례하는 상관관계를 가지고 있는 것을 알 수 있습니다.

 

다음으로는 연료, 차종별 COMB를 그래프화 하였습니다.

 

###일반가솔린 차량만 보기
df_fuel_X = df[df['FUEL'] == 'X']

order_by_efficiency_X = df_fuel_X.groupby('VEHICLE CLASS')['COMB (L/100 km)'].mean().sort_values(ascending=False).index

plt.figure(figsize=(12, 8))
sns.barplot(
    data=df_fuel_X,
    x='COMB (L/100 km)',
    y='VEHICLE CLASS',
    order=order_by_efficiency_X,
    hue='FUEL',
    orient='h',          # 수평 막대 그래프
    palette=['green']
)

plt.title('일반 가솔린(X) 차량의 차종별 평균 복합 연비', fontsize=16, pad=20)
plt.xlabel('평균 복합 연비 (L/100 km)', fontsize=12)
plt.ylabel('차종', fontsize=12)
plt.grid(axis='x', linestyle='--', alpha=0.6)

 

###고급가솔린 차량만 보기
df_fuel_Z = df[df['FUEL'] == 'Z']

order_by_efficiency_Z = df_fuel_Z.groupby('VEHICLE CLASS')['COMB (L/100 km)'].mean().sort_values(ascending=False).index

plt.figure(figsize=(12, 8))
sns.barplot(
    data=df_fuel_Z,
    x='COMB (L/100 km)',
    y='VEHICLE CLASS',
    order=order_by_efficiency_Z,
    hue='FUEL',
    orient='h',          # 수평 막대 그래프
    palette=['red']
)

plt.title('고급 가솔린(Z) 차량의 차종별 평균 복합 연비', fontsize=16, pad=20)
plt.xlabel('평균 복합 연비 (L/100 km)', fontsize=12)
plt.ylabel('차종', fontsize=12)
plt.grid(axis='x', linestyle='--', alpha=0.6)

 

###디젤 차량만 보기
df_fuel_D = df[df['FUEL'] == 'D']

order_by_efficiency_D = df_fuel_D.groupby('VEHICLE CLASS')['COMB (L/100 km)'].mean().sort_values(ascending=False).index

plt.figure(figsize=(12, 8))
sns.barplot(
    data=df_fuel_D,
    x='COMB (L/100 km)',
    y='VEHICLE CLASS',
    order=order_by_efficiency_D,
    hue='FUEL',
    orient='h',         # 수평 막대 그래프
    palette=['purple']
)

plt.title('디젤(D) 차량의 차종별 평균 복합 연비', fontsize=16, pad=20)
plt.xlabel('평균 복합 연비 (L/100 km)', fontsize=12)
plt.ylabel('차종', fontsize=12)
plt.grid(axis='x', linestyle='--', alpha=0.6)

###에탄올 차량만 보기
df_fuel_E = df[df['FUEL'] == 'E']

order_by_efficiency_E = df_fuel_E.groupby('VEHICLE CLASS')['COMB (L/100 km)'].mean().sort_values(ascending=False).index

plt.figure(figsize=(12, 8))
sns.barplot(
    data=df_fuel_E,
    x='COMB (L/100 km)',
    y='VEHICLE CLASS',
    order=order_by_efficiency_E,
    hue='FUEL',
    orient='h',          # 수평 막대 그래프
    palette=['blue']
)

plt.title('에탄올(E) 차량의 차종별 평균 복합 연비', fontsize=16, pad=20)
plt.xlabel('평균 복합 연비 (L/100 km)', fontsize=12)
plt.ylabel('차종', fontsize=12)
plt.grid(axis='x', linestyle='--', alpha=0.6)

### 차량만 보기
df_fuel_N = df[df['FUEL'] == 'N']

order_by_efficiency_N = df_fuel_N.groupby('VEHICLE CLASS')['COMB (L/100 km)'].mean().sort_values(ascending=False).index

plt.figure(figsize=(12, 8))
sns.barplot(
    data=df_fuel_N,
    x='COMB (L/100 km)',
    y='VEHICLE CLASS',
    order=order_by_efficiency_N,
    hue='FUEL',
    orient='h',          # 수평 막대 그래프
    palette=['orange']
)

plt.title('천연가스(N) 차량의 차종별 평균 복합 연비', fontsize=16, pad=20)
plt.xlabel('평균 복합 연비 (L/100 km)', fontsize=12)
plt.ylabel('차종', fontsize=12)
plt.grid(axis='x', linestyle='--', alpha=0.6)

 

5. 오늘 소감

뭔가 데이터를 처리하면서 생각보다 할 수 있는게 많다고 생각했고 앞으로도 잘 해낼수 있다는 생각이 듭니다.

시각화를 하면서 아직은 미숙하지만 속도를 높여서 좀더 빠르게 데이터를 처리하고 시각화하는게 필요하다고 생각합니다.

그리고 데이터 분석에서 가장 중요한건 시각화를 하기 이전에 무엇을 보여주고 싶은지 무슨 문제를 해결하기 위해 데이터를 분석할 건지 명확하게 정의하고 프로젝트를 진행해야 시간도 절약할 수 있고 명확한 결과를 낼 수 있다고 느꼈습니다.