카테고리 없음

기초 프로젝트_DAY4_최종 결론 도출

iron-min 2025. 10. 16. 22:31

오늘은 최종 코드 및 결과를 도출했습니다.

 

 

 

1. 데이터의 배경 인사이트 도출

emissions_group = df.groupby('YEAR')['EMISSIONS'].mean().reset_index()

plt.figure(figsize=(15,5))

# 1. 전체 추세 (검은색 선 + 점)
sns.lineplot(x='YEAR', y='EMISSIONS', data=emissions_group,
             color='black', linewidth=2, marker='o')

# 2. 2014, 2015년 강조 (빨간 점 + 값 표시)
highlight = emissions_group[emissions_group['YEAR'].isin([2014, 2015])]
sns.scatterplot(x='YEAR', y='EMISSIONS', data=highlight,
                color='red', s=120, zorder=5)

# 점 위에 값 표시
for x, y in zip(highlight['YEAR'], highlight['EMISSIONS']):
    plt.text(x, y+1, f"{y:.1f}", ha='center', va='bottom',
             fontsize=10, color='red', weight='bold')

plt.title('연도별 평균 배출량 추세 (2014·2015 강조)', fontsize=15)
plt.xlabel('연도')
plt.ylabel('평균 배출량')
plt.grid(axis='y', linestyle=':', alpha=0.6)
plt.show()

 

 

grouped = df.groupby(['FUEL','YEAR'])['EMISSIONS'].mean().reset_index()

plt.figure(figsize=(15,5))

# 1. 모든 연료 추세선 (기본 색상 팔레트)
sns.lineplot(data=grouped, x='YEAR', y='EMISSIONS', hue='FUEL', linewidth=1.5, alpha=0.7)

# 2. 디젤(D)만 다시 덮어그려서 강조
diesel = grouped[grouped['FUEL'] == 'D']
sns.lineplot(data=diesel, x='YEAR', y='EMISSIONS',
             color='red', linewidth=3, marker='o', label='Diesel (강조)')

plt.title('연도별 연료별 평균 배출량', fontsize=15)
plt.xlabel('연도')
plt.ylabel('평균 배출량')
plt.grid(axis='y', linestyle=':', alpha=0.6)
plt.legend()
plt.show()

 

2. 각 요인별 탄소배출량에 미치는 영향 분석

 

corr_df = df.corr(numeric_only=True)

# EMISSIONS과의 상관계수만 추출
em_corr = corr_df['EMISSIONS'].drop('EMISSIONS')
print(em_corr)

highlight_cols = ['ENGINE SIZE', 'CYLINDERS', 'COMB (L/100 km)']

plt.figure(figsize=(10,6))
colors = ['red' if col in highlight_cols else 'skyblue' for col in em_corr.index]

ax = sns.barplot(x=em_corr.index, y=em_corr.values, palette=colors, edgecolor='black')

# 각 막대 위에 수치 표시
for i, (col, val) in enumerate(zip(em_corr.index, em_corr.values)):
    color = 'red' if col in highlight_cols else 'black'
    plt.text(i, val + (0.02 if val >= 0 else -0.05), f"{val:.2f}", 
             ha='center', va='bottom' if val >= 0 else 'top', 
             fontsize=10, fontweight='bold', color=color)

plt.title("Correlation with EMISSIONS", fontsize=15)
plt.xticks(rotation=45)
plt.axhline(0, color='black', linewidth=0.8)  # 0 기준선
plt.grid(axis='y', linestyle=':', alpha=0.6)  # y축 보조선
plt.tight_layout()
plt.show()

3. 주요 요인과 탄소배출량이 미치는 영향 시각화

# 컬럼
cols = ['FUEL', 'SIZE CLASS', 'COMB (L/100 km)', 'EMISSIONS']
df = df[cols].dropna()

# 연료
fuel_map = {
    'X': '일반 가솔린',
    'Z': '고급 가솔린',
    'E': '에탄올 혼합',
    'N': '천연가스',
    'D': '디젤'
}
df['FUEL_NAME'] = df['FUEL'].map(fuel_map)

# FUELE, SIZE CLASS
fuels = ['일반 가솔린', '고급 가솔린', '에탄올 혼합', '천연가스', '디젤']
sizes = sorted(df['SIZE CLASS'].unique())[:3]


# 2 시각화: 3행 × 5열

fig, axes = plt.subplots(len(sizes), len(fuels), figsize=(22, 12), sharex=False, sharey=False)

for i, size in enumerate(sizes):
    for j, fuel in enumerate(fuels):
        ax = axes[i, j]

        subset = df[(df['FUEL_NAME'] == fuel) & (df['SIZE CLASS'] == size)]
        if subset.empty:
            ax.set_visible(False)
            continue

        # 연비 기준
        subset = subset.sort_values('COMB (L/100 km)').reset_index(drop=True)

        # x축 재배치 (간격 균등)
        x_vals = np.linspace(subset['COMB (L/100 km)'].min(),
                             subset['COMB (L/100 km)'].max(),
                             len(subset))

        # 점 + 선
        ax.plot(x_vals,
                subset['EMISSIONS'],
                marker='o',
                linestyle='-',
                alpha=0.8,
                color=sns.color_palette('tab10')[j % 10])

        ax.set_title(f"{fuel} | {size}", fontsize=11)
        ax.tick_params(axis='x', labelrotation=35)
        if i == len(sizes)-1:
            ax.set_xlabel("연비 (COMB L/100km)")
        if j == 0:
            ax.set_ylabel("배출량 (EMISSIONS)")

plt.suptitle("연비 vs 배출량 — 연료별 × 차량크기별 (15개 조합)", fontsize=16)
plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.show()

 

 

# FUEL 코드 → 한글명
fuel_map = {
    'X': '일반가솔린',
    'Z': '고급가솔린',
    'E': '에탄올 혼합음료',
    'N': '압축 천연가스',
    'D': '디젤 엔진',
}
df = pd.read_csv(r'C:\Users\hoyho\OneDrive\바탕 화면\부트캠프\기초프로젝트\python_folder\기초프로젝트\전처리_데이터_2차.csv')

needed = ['FUEL', 'SIZE CLASS', 'ENGINE SIZE', 'COMB (L/100 km)']
missing = [c for c in needed if c not in df.columns]
if missing:
    raise KeyError(f"필수 컬럼 누락: {missing}\n현재 컬럼: {df.columns.tolist()}")

df = df[needed].dropna().copy()
df = df[(df['ENGINE SIZE'] > 0) & (df['COMB (L/100 km)'] > 0)].copy()

# 이상치 완화
def clip_iqr(s):
    q1, q3 = s.quantile(0.25), s.quantile(0.75)
    iqr = q3 - q1
    low, high = q1 - 1.5*iqr, q3 + 1.5*iqr
    return s.clip(lower=low, upper=high)

if USE_IQR:
    df['ENGINE SIZE'] = clip_iqr(df['ENGINE SIZE'])
    df['COMB (L/100 km)'] = clip_iqr(df['COMB (L/100 km)'])

# FUEL 한글명
df['FUEL_NAME'] = df['FUEL'].map(fuel_map)

fuel_order = [c for c in ['X','Z','E','N','D'] if c in df['FUEL'].unique()]
size_levels = list(df['SIZE CLASS'].unique())


nrows, ncols = len(size_levels), len(fuel_order)
fig, axes = plt.subplots(nrows, ncols, figsize=(4.8*ncols, 4.0*nrows), sharex=False, sharey=False)

# axes
if nrows == 1 and ncols == 1:
    axes = np.array([[axes]])
elif nrows == 1:
    axes = axes.reshape(1, -1)
elif ncols == 1:
    axes = axes.reshape(-1, 1)

for i, size in enumerate(size_levels):
    for j, fcode in enumerate(fuel_order):
        ax = axes[i, j]
        sub = df[(df['FUEL'] == fcode) & (df['SIZE CLASS'] == size)][['ENGINE SIZE', 'COMB (L/100 km)']].dropna()
        if sub.empty:
            ax.set_visible(False)
            continue

        # x를 반올림 그룹으로 묶기
        sub = sub.copy()
        sub['ENG_grp'] = sub['ENGINE SIZE'].round(DEC)

        # 그룹 통계: 합/최대/최소/개수
        g = sub.groupby('ENG_grp')['COMB (L/100 km)']
        stats = pd.DataFrame({
            'COMB_sum': g.sum(),
            'COMB_max': g.max(),
            'COMB_min': g.min(),
            'n': g.size(),
        }).reset_index().rename(columns={'ENG_grp': 'ENGINE_avg'})

        # 기준값 선택
        if BASE.lower() == "max":

            stats['gap_sum'] = stats['n'] * stats['COMB_max'] - stats['COMB_sum']
            base_label = "최대값 대비 갭 합(Σ[max−y])"
        elif BASE.lower() == "min":

            stats['gap_sum'] = stats['COMB_sum'] - stats['n'] * stats['COMB_min']
            base_label = "최소값 대비 갭 합(Σ[y−min])"
        else:
            raise ValueError("BASE는 'max' 또는 'min' 중 하나여야 합니다.")

        stats = stats.sort_values('ENGINE_avg')

        # 선 그래프
        ax.plot(
            stats['ENGINE_avg'],
            stats['gap_sum'],
            marker='o', markersize=6,
            linestyle='-', linewidth=2, alpha=0.9,
        )

        # 제목
        fuel_name = fuel_map.get(fcode, fcode)
        size_name = str(size).title()
        ax.set_title(f"{fuel_name}&{size_name}", fontsize=12)

        if i == nrows - 1:
            ax.set_xlabel(f"엔진 크기 (L)  [그룹 반올림: {DEC}자리]")
        if j == 0:
            ax.set_ylabel(f"{base_label} (L/100km)")

        ax.grid(True, linestyle=':', alpha=0.5)

plt.suptitle(f"엔진 크기 vs {base_label} — FUEL×SIZE CLASS", fontsize=15)
plt.tight_layout(rect=[0, 0, 1, 0.95])
plt.show()

 

3. 요인이 미치는 영향 분석

fuel_map = {'X':'일반가솔린','Z':'고급가솔린','E':'에탄올 혼합음료','N':'압축 천연가스','D':'디젤 엔진'}

def clip_iqr(s):
    q1, q3 = s.quantile(0.25), s.quantile(0.75)
    iqr = q3 - q1
    return s.clip(lower=q1-1.5*iqr, upper=q3+1.5*iqr)

def fmt_num(x, dec=DEC):
    if float(x).is_integer():
        return str(int(x))
    s = f"{x:.{dec}f}".rstrip('0').rstrip('.')
    return s if s else "0"

need = ['FUEL','SIZE CLASS','ENGINE SIZE','COMB (L/100 km)']
df = pd.read_csv(PATH)
missing = [c for c in need if c not in df.columns]
if missing:
    raise KeyError(f"필수 컬럼 누락: {missing}\n현재 컬럼: {df.columns.tolist()}")

df = df[need].dropna()
df = df[(df['ENGINE SIZE']>0) & (df['COMB (L/100 km)']>0)].copy()
if USE_IQR:
    df['ENGINE SIZE'] = clip_iqr(df['ENGINE SIZE'])
    df['COMB (L/100 km)'] = clip_iqr(df['COMB (L/100 km)'])

df['EFFICIENCY (km/L)'] = 100.0 / df['COMB (L/100 km)']
df['연료'] = df['FUEL'].map(fuel_map)
df['차량크기'] = df['SIZE CLASS']

rows = []
for (fuel, size), g in df.groupby(['연료','차량크기'], dropna=False):
    s = g[['ENGINE SIZE','EFFICIENCY (km/L)']].copy()
    if s.empty:
        continue
    s['ENG_grp'] = s['ENGINE SIZE'].round(DEC)
    series = (s.groupby('ENG_grp', as_index=False)['EFFICIENCY (km/L)']
                .mean()
                .rename(columns={'ENG_grp':'ENGINE_avg',
                                 'EFFICIENCY (km/L)':'EFF_mean'})
                .sort_values('ENGINE_avg'))
    if len(series) < 2:
        continue

    x = series['ENGINE_avg'].to_numpy(float)
    y = series['EFF_mean'].to_numpy(float)
    dx = x[1:] - x[:-1]
    dy = y[1:] - y[:-1]
    slope = dy / dx
    pos_idx = np.where(slope > 0)[0]
    if len(pos_idx) == 0:
        continue
    k = pos_idx[np.argmax(slope[pos_idx])]
    x1, x2, m = x[k], x[k+1], slope[k]

    rows.append({
        '연료': fuel,
        '차량크기': size,
        '최대양의기울기(dy/dx,  km/L  per  L)': m,
        '기울기최대구간{ENGINE SIZE}': f"[{fmt_num(x1)}, {fmt_num(x2)}]"
    })

result = pd.DataFrame(rows).sort_values(
    ['연료','차량크기','최대양의기울기(dy/dx,  km/L  per  L)'],
    ascending=[True, True, False]
).reset_index(drop=True)


if not result.empty:
    disp = result.copy()
    disp.index = disp.index + 1
    disp_styler = (
        disp.style
        .format({'최대양의기울기(dy/dx,  km/L  per  L)': '{:.4f}'})
        .set_table_styles([
            {'selector':'th', 'props':'text-align:center; font-weight:bold; border-bottom:1px solid #bbb;'},
            {'selector':'td', 'props':'text-align:center; border-bottom:1px solid #eee; padding:6px 10px;'},
            {'selector':'table', 'props':'border-collapse:collapse; font-size:14px;'}
        ])
        .hide(axis='columns', subset=[])
    )
    display(HTML("<div style='margin:6px 0;'></div>"))
    display(disp_styler)
else:
    print("(양의 기울기 구간 없음)")

# 엑셀 저장
with pd.ExcelWriter(OUT_XLSX, engine="openpyxl") as w:
    if not result.empty:
        result_x = result.copy()
        result_x['최대양의기울기(dy/dx,  km/L  per  L)'] = result_x['최대양의기울기(dy/dx,  km/L  per  L)'].round(6)
        result_x.to_excel(w, sheet_name="조합별_최대양기울기", index=False)
    df.to_excel(w, sheet_name="원자료", index=False)

print(f" 엑셀 파일 : {OUT_XLSX}")

# FUEL 코드 → 한글명
fuel_map = {
    'X': '일반가솔린',
    'Z': '고급가솔린',
    'E': '에탄올 혼합음료',
    'N': '압축 천연가스',
    'D': '디젤 엔진',
}

df = pd.read_csv(path)

needed = ['FUEL', 'SIZE CLASS', 'CYLINDERS', 'EMISSIONS']
missing = [c for c in needed if c not in df.columns]
if missing:
    raise KeyError(f"필수 컬럼 누락: {missing}\n현재 컬럼: {df.columns.tolist()}")

df = df[needed].dropna().copy()
df = df[(df['CYLINDERS'] > 0) & (df['EMISSIONS'] > 0)].copy()

# 이상치 완화 함수
def clip_iqr(s):
    q1, q3 = s.quantile(0.25), s.quantile(0.75)
    iqr = q3 - q1
    low, high = q1 - 1.5*iqr, q3 + 1.5*iqr
    return s.clip(lower=low, upper=high)

if USE_IQR:
    df['CYLINDERS'] = clip_iqr(df['CYLINDERS'])
    df['EMISSIONS'] = clip_iqr(df['EMISSIONS'])

# FUEL 한글명
df['FUEL_NAME'] = df['FUEL'].map(fuel_map)

fuel_order = [c for c in ['X','Z','E','N','D'] if c in df['FUEL'].unique()]
size_levels = list(df['SIZE CLASS'].unique())

nrows, ncols = len(size_levels), len(fuel_order)
fig, axes = plt.subplots(nrows, ncols, figsize=(4.8*ncols, 4.0*nrows), sharex=False, sharey=False)

# axes reshape
if nrows == 1 and ncols == 1:
    axes = np.array([[axes]])
elif nrows == 1:
    axes = axes.reshape(1, -1)
elif ncols == 1:
    axes = axes.reshape(-1, 1)

for i, size in enumerate(size_levels):
    for j, fcode in enumerate(fuel_order):
        ax = axes[i, j]
        sub = df[(df['FUEL'] == fcode) & (df['SIZE CLASS'] == size)][['CYLINDERS','EMISSIONS']].dropna()
        if sub.empty:
            ax.set_visible(False)
            continue

        # 그룹핑 (실린더 수 기준)
        sub['CYL_grp'] = sub['CYLINDERS'].round(DEC)

        g = sub.groupby('CYL_grp')['EMISSIONS']
        stats = pd.DataFrame({
            'EM_sum': g.sum(),
            'EM_max': g.max(),
            'EM_min': g.min(),
            'n': g.size(),
        }).reset_index().rename(columns={'CYL_grp': 'CYL_avg'})

        # 기준값에 따른 갭 합
        if BASE.lower() == "max":
            stats['gap_sum'] = stats['n'] * stats['EM_max'] - stats['EM_sum']
            base_label = "최대값 대비 갭 합(Σ[max−y])"
        elif BASE.lower() == "min":
            stats['gap_sum'] = stats['EM_sum'] - stats['n'] * stats['EM_min']
            base_label = "최소값 대비 갭 합(Σ[y−min])"
        else:
            raise ValueError("BASE는 'max' 또는 'min' 중 하나여야 합니다.")

        stats = stats.sort_values('CYL_avg')

        # 선 그래프
        ax.plot(stats['CYL_avg'], stats['gap_sum'],
                marker='o', markersize=6,
                linestyle='-', linewidth=2, alpha=0.9)

        # 제목
        fuel_name = fuel_map.get(fcode, fcode)
        size_name = str(size).title()
        ax.set_title(f"{fuel_name} & {size_name}", fontsize=12)

        if i == nrows - 1:
            ax.set_xlabel("실린더 수 (그룹)")
        if j == 0:
            ax.set_ylabel(f"{base_label}")

        ax.grid(True, linestyle=':', alpha=0.5)

plt.suptitle(f"실린더 수 vs {base_label} — FUEL×SIZE CLASS", fontsize=15)
plt.tight_layout(rect=[0, 0, 1, 0.95])
plt.show()

 

 

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

# 단종된 회사 삭제
drop_makes = ['OLDSMOBILE', 'PLYMOUTH', 'PONTIAC',
              'SAAB', 'SATURN', 'ISUZU', 'SUZUKI']
df1 = df1[ df1['MAKE'].isin(drop_makes) == False ]

# 사용하지 않는 컬럼 삭제
df1 = df1.drop(columns = ['FUEL CONSUMPTION', 'HWY (L/100 km)'])

# 같은 VEHICLE CLASS 문자 변경
df1['VEHICLE CLASS'] = df1['VEHICLE CLASS'].str.upper()
df1['VEHICLE CLASS'] = df1['VEHICLE CLASS'].str.replace(r"\s+", "", regex=True)   # 모든 공백 제거(스페이스 바 말고)
df1['VEHICLE CLASS'] = df1['VEHICLE CLASS'].str.replace(':','-')   # str 안쓰면 값 전체가 ':'가 아니면 안바뀜.

# 같은 MAKE 문자 변경
df1['MAKE'] = df1['MAKE'].str.strip()
df1['MAKE'] = df1['MAKE'].str.upper()
df1['VEHICLE CLASS'].nunique()   # 17
df1['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' : 'OTHER'
}

df1['SIZE CLASS'] = df1['VEHICLE CLASS'].map(mapping).fillna('OTHER')
df1[df1['SIZE CLASS'] == 'OTHER']
df1.drop(df1[ df1['SIZE CLASS'] == 'OTHER'].index, inplace = True)

df1.info()
# 평균 연비 집계
grouped_transmission = (
    df1.groupby(['TRANSMISSION','SIZE CLASS','FUEL'])['COMB (L/100 km)']
      .mean()
      .reset_index()
)

# 소형+가솔린만 추출 (복사본으로 안전하게)
small_X = grouped_transmission[
    (grouped_transmission['SIZE CLASS']=='SMALL') & (grouped_transmission['FUEL']=='X')
].copy()

# 점수: (max - value) → 값이 작을수록(연비 좋을수록) 점수 큼
max_val = small_X['COMB (L/100 km)'].max()
small_X['EFFICIENCY'] = max_val - small_X['COMB (L/100 km)']

# 변속기 숫자 추출 (예: 'A8' → 8, 'CVT' → NaN)
small_X['GEAR_NUM'] = small_X['TRANSMISSION'].str.extract(r'(\d+)').astype(float)

# 효율 점수 기준 정렬
small_X = small_X.sort_values('EFFICIENCY', ascending=False)

# 시각화
plt.figure(figsize=(15,5))
sns.barplot(
    data=small_X,
    x='TRANSMISSION',
    y='EFFICIENCY',
    order=small_X['TRANSMISSION']   # 정렬된 순서 그대로 반영
)
plt.title('소형/가솔린 변속기별 효율 점수 (정렬)', fontsize=15)
plt.xlabel('변속기')
plt.ylabel('효율 점수 (클수록 효율 좋음)')
plt.grid(axis='y', linestyle=':', alpha=0.6)
plt.show()

# 원래 L/100km 값 기준으로 최적/최악 뽑기
max_row = small_X.loc[small_X['COMB (L/100 km)'].idxmax()]  # 연비 최악 (값이 가장 큼)
min_row = small_X.loc[small_X['COMB (L/100 km)'].idxmin()]  # 연비 최적 (값이 가장 작음)

print("연비가 가장 낮은 차량 (연비 최악):")
print(max_row)

print("\n연비가 가장 좋은 차량 (연비 최적):")
print(min_row)

# 평균 연비 집계
grouped_transmission = (
    df1.groupby(['TRANSMISSION','SIZE CLASS','FUEL'])['COMB (L/100 km)']
      .mean()
      .reset_index()
)

# 소형+가솔린만 추출 (복사본으로 안전하게)
small_X = grouped_transmission[
    (grouped_transmission['SIZE CLASS']=='SMALL') & (grouped_transmission['FUEL']=='Z')
].copy()

# 점수: (max - value) → 값이 작을수록(연비 좋을수록) 점수 큼
max_val = small_X['COMB (L/100 km)'].max()
small_X['EFFICIENCY'] = max_val - small_X['COMB (L/100 km)']

# 변속기 숫자 추출 (예: 'A8' → 8, 'CVT' → NaN)
small_X['GEAR_NUM'] = small_X['TRANSMISSION'].str.extract(r'(\d+)').astype(float)

# 효율 점수 기준 정렬
small_X = small_X.sort_values('EFFICIENCY', ascending=False)

# 시각화
plt.figure(figsize=(15,5))
sns.barplot(
    data=small_X,
    x='TRANSMISSION',
    y='EFFICIENCY',
    order=small_X['TRANSMISSION']   # 정렬된 순서 그대로 반영
)
plt.title('소형/고급가솔린 변속기별 효율 점수 (정렬)', fontsize=15)
plt.xlabel('변속기')
plt.ylabel('효율 점수 (클수록 효율 좋음)')
plt.grid(axis='y', linestyle=':', alpha=0.6)
plt.show()

# 원래 L/100km 값 기준으로 최적/최악 뽑기
max_row = small_X.loc[small_X['COMB (L/100 km)'].idxmax()]  # 연비 최악 (값이 가장 큼)
min_row = small_X.loc[small_X['COMB (L/100 km)'].idxmin()]  # 연비 최적 (값이 가장 작음)

print("연비가 가장 낮은 차량 (연비 최악):")
print(max_row)

print("\n연비가 가장 좋은 차량 (연비 최적):")
print(min_row)

# 평균 연비 집계
grouped_transmission = (
    df1.groupby(['TRANSMISSION','SIZE CLASS','FUEL'])['COMB (L/100 km)']
      .mean()
      .reset_index()
)

# 소형+가솔린만 추출 (복사본으로 안전하게)
small_X = grouped_transmission[
    (grouped_transmission['SIZE CLASS']=='SMALL') & (grouped_transmission['FUEL']=='D')
].copy()

# 점수: (max - value) → 값이 작을수록(연비 좋을수록) 점수 큼
max_val = small_X['COMB (L/100 km)'].max()
small_X['EFFICIENCY'] = max_val - small_X['COMB (L/100 km)']

# 변속기 숫자 추출 (예: 'A8' → 8, 'CVT' → NaN)
small_X['GEAR_NUM'] = small_X['TRANSMISSION'].str.extract(r'(\d+)').astype(float)

# 효율 점수 기준 정렬
small_X = small_X.sort_values('EFFICIENCY', ascending=False)

# 시각화
plt.figure(figsize=(15,5))
sns.barplot(
    data=small_X,
    x='TRANSMISSION',
    y='EFFICIENCY',
    order=small_X['TRANSMISSION']   # 정렬된 순서 그대로 반영
)
plt.title('소형/디젤 변속기별 효율 점수 (정렬)', fontsize=15)
plt.xlabel('변속기')
plt.ylabel('효율 점수 (클수록 효율 좋음)')
plt.grid(axis='y', linestyle=':', alpha=0.6)
plt.show()

# 원래 L/100km 값 기준으로 최적/최악 뽑기
max_row = small_X.loc[small_X['COMB (L/100 km)'].idxmax()]  # 연비 최악 (값이 가장 큼)
min_row = small_X.loc[small_X['COMB (L/100 km)'].idxmin()]  # 연비 최적 (값이 가장 작음)

print("연비가 가장 낮은 차량 (연비 최악):")
print(max_row)

print("\n연비가 가장 좋은 차량 (연비 최적):")
print(min_row)