HOWTO · Pandas
Pandas에서 숫자형 DataFrame 열을 정규화하는 세 가지 방법
숫자형 Pandas DataFrame 열에 대한 평균(z-점수) 표준화, min-max 스케일링, 분위수 정규화를 공식과 재사용 가능한 예제와 함께 비교합니다.
이 페이지의 내용
Pandas DataFrame의 숫자형 열을 재조정하려면 세 가지 방법 중에서 선택할 수 있습니다. 평균 정규화(z-score 표준화)는 각 열의 중심을 평균으로 옮기고 표준편차로 나누며, min-max 스케일링은 상수 열이 아닌 각 열의 값을 0–1 범위로 변환합니다. 분위수 정규화는 순위에 따라 값을 공통 분포에 맞춥니다. 적절한 방법은 모델에 필요한 값의 범위, 이상치에 대한 민감도, 열들의 분포를 서로 비슷하게 맞춰야 하는지에 따라 달라집니다.
Pandas의 데이터 정규화
정규화는 값의 범위를 재조정하고, 표준화는 평균을 중심으로 값을 옮긴 뒤 표준편차 단위로 나타냅니다. 이 가이드에서는 열별 변환 방법 세 가지를 살펴봅니다. Pandas에는 이러한 수식을 한 번에 적용하는 전용 DataFrame 메서드가 없지만, 산술 연산과 순위 연산을 사용하면 각각 쉽게 구현할 수 있습니다.
예제에서는 숫자형 열이 네 개인 작고 결정적인 DataFrame을 공통으로 사용합니다. 각 변환은 열별로 적용되므로 열 이름과 행 인덱스는 그대로 유지됩니다.
import pandas as pd
df = pd.DataFrame({
"A": [1, 2, 3, 4],
"B": [10, 20, 30, 40],
"C": [4, 1, 3, 2],
"D": [5, 5, 5, 5],
})
print(df)
A B C D
0 1 10 4 5
1 2 20 1 5
2 3 30 3 5
3 4 40 2 5
D 열은 상수 열로 설정해 min-max 섹션에서 그 동작을 명확히 보여 줍니다. 아래 예제는 각각 독립적으로 실행할 수 있으며 동일한 입력 데이터를 다시 만듭니다.
평균 정규화로 Pandas DataFrame 정규화하기
평균 기반 수식은 (x - mean) / standard deviation이며, 각 열에 따로 계산합니다. 이는 z-score 표준화로, 변환된 각 열의 평균은 0에 가까워지고 값은 0–1 범위에 제한되지 않고 표준편차 단위로 표현됩니다. Pandas의 Series.std()는 기본적으로 표본 표준편차(ddof=1)를 사용합니다. 모집단 표준편차가 필요한 계산이라면 ddof=0을 사용하세요.
import pandas as pd
df = pd.DataFrame({
"A": [1, 2, 3, 4],
"B": [10, 20, 30, 40],
"C": [4, 1, 3, 2],
"D": [5, 5, 5, 5],
})
mean_norm = df.apply(lambda column: (column - column.mean()) / column.std(), axis=0)
print(mean_norm.round(3))
A B C D
0 -1.162 -1.162 1.162 NaN
1 -0.387 -0.387 -1.162 NaN
2 0.387 0.387 0.387 NaN
3 1.162 1.162 -0.387 NaN
이 변환은 중심이 맞춰진 비슷한 척도를 사용하는 방법에 유용합니다. 상수 열의 표준편차는 0이므로 이 수식은 해당 열에 결측값을 만듭니다. 애플리케이션에 맞게 해당 특성을 제거할지 별도로 처리할지 결정하세요.
min-max 정규화로 Pandas DataFrame 정규화하기
각 열에 min-max 스케일링 수식 (x - min) / (max - min)을 적용합니다. 상수 열이 아닌 열은 최솟값이 0, 최댓값이 1이 되며 나머지 값은 그 사이에 비례해 배치됩니다. 아래 헬퍼는 df_input 인자를 일관되게 사용하며, 값의 변화가 없는 특성에 흔히 사용하는 중립적인 선택으로 상수 열을 0에 매핑합니다.
import pandas as pd
def minmax_norm(df_input):
column_range = df_input.max() - df_input.min()
scaled = (df_input - df_input.min()) / column_range
return scaled.fillna(0)
df = pd.DataFrame({
"A": [1, 2, 3, 4],
"B": [10, 20, 30, 40],
"C": [4, 1, 3, 2],
"D": [5, 5, 5, 5],
})
print(minmax_norm(df).round(3))
A B C D
0 0.000 0.000 1.000 0.0
1 0.333 0.333 0.000 0.0
2 0.667 0.667 0.667 0.0
3 1.000 1.000 0.333 0.0
고정된 범위가 중요할 때 min-max 스케일링을 사용할 수 있습니다. 관측된 최솟값과 최댓값이 척도를 결정하므로 극단값이 있으면 해당 열의 나머지 값들이 좁은 구간에 몰릴 수 있습니다. 헬퍼 마지막의 fillna(0)은 상수 숫자형 열을 0으로 매핑하지만, 입력에 이미 있던 모든 결측값도 0으로 바꿉니다. 평균 대치를 선호한다면 헬퍼를 호출하기 전에 결측값을 채우세요. 예를 들어 minmax_norm(df_input.fillna(df_input.mean()))처럼 사용할 수 있습니다. 데이터에 맞는 대치 정책을 선택하세요.
분위수 정규화로 Pandas DataFrame 정규화하기
열들이 같은 기본 분포를 공유한다고 예상될 때 분위수 정규화를 사용할 수 있습니다. 각 열을 정렬하고, 모든 열에서 각 순위에 해당하는 값들의 평균을 구한 다음, 그 순위 평균을 원래 행에 다시 매핑합니다. 다른 두 방법과 달리 열의 경험적 분포를 맞추도록 값을 바꾸므로, 공통 분포라는 가정이 타당할 때만 사용하세요.
이 구현은 rank(method="min")을 사용합니다. 동률인 값에는 해당 동률 그룹에서 가장 작은 순위를 부여합니다. 동률 순위의 평균을 내지 않으므로 결과 분포가 서로 다를 수 있습니다. 공통 예제에서 D 열은 상수입니다. 네 값 모두 최솟값 순위에서 동률이므로 공통 순위 값 전체에 걸쳐 배치되는 대신 동일한 순위 평균으로 매핑됩니다.
import numpy as np
import pandas as pd
def quantile_norm(df_input):
sorted_values = np.sort(df_input.to_numpy(), axis=0)
rank_means = sorted_values.mean(axis=1)
rank_to_mean = pd.Series(rank_means, index=np.arange(1, len(rank_means) + 1))
ranks = df_input.rank(method="min").stack().astype(int)
return ranks.map(rank_to_mean).unstack()
df = pd.DataFrame({
"A": [1, 2, 3, 4],
"B": [10, 20, 30, 40],
"C": [4, 1, 3, 2],
"D": [5, 5, 5, 5],
})
print(quantile_norm(df).round(3))
A B C D
0 4.25 4.25 13.25 4.25
1 7.25 7.25 4.25 4.25
2 10.25 10.25 10.25 4.25
3 13.25 13.25 7.25 4.25
상수 D 열은 공통 분포 가정이 중요한 이유를 보여 줍니다. 반복된 값 모두 최솟값 순위를 받아 4.25로 매핑되므로 다른 열의 경험적 분포와 일치하지 않습니다. 일반적인 숫자형 특성에는 각 방법의 목적을 기준으로 선택하세요. 중심을 맞추고 표준편차로 척도를 조정하려면 z-score를, 이상치에 주의하면서 범위를 제한하려면 min-max를, 데이터가 정당화하는 경우 열의 분포를 맞추려면 분위수 정규화를 사용하세요.