세조목

Python 개념 정리(변수 할당)(24.05.09) 본문

데이터 분석 공부/Python

Python 개념 정리(변수 할당)(24.05.09)

세조목 2024. 5. 9. 20:20

여러 번 나눠서 돌려야하는 코드를 함수를 사용해서 한꺼번에 돌리는 경우가 종종 있습니다.

금일 머신러닝 공부를 하면서도 그렇게 함수를 만들어서 코드를 돌렸는데요,

이해가 되지 않는 부분이 있었습니다.

def get_numeric_sc(df):
  from sklearn.preprocessing import StandardScaler, MinMaxScaler
  sd_sc = StandardScaler()
  mm_sc = MinMaxScaler()

  sd_sc.fit(train_df_2[['Fare']])
  df['Fare_sd_sc'] = sd_sc.transform(df[['Fare']])

  mm_sc.fit(train_df_2[['Age', 'Family']])
  df[['Age_mm_sc', 'Family_mm_sc']] = mm_sc.transform(df[['Age', 'Family']])

  return df
get_numeric_sc(train_df_2)

이같은 코드를 돌리면 아래와 같이 기존 train_df_2 데이터프레임에 새로운 컬럼들이 추가됩니다.

 

그런데 아래 또 다른 함수를 돌리면 새롭게 추가하고자 하는 컬럼이 train_df_2 데이터프레임에 붙지 않습니다.

def get_category(df):
  from sklearn.preprocessing import LabelEncoder, OneHotEncoder
  le = LabelEncoder()
  le2 = LabelEncoder()
  oe = OneHotEncoder()

  le.fit(train_df_2[['Pclass']])
  df['Pclass_le'] = le.transform(df['Pclass'])

  le2.fit(train_df_2[['Sex']])
  df['Sex_le'] = le2.transform(df['Sex'])

  oe.fit(train_df_2[['Embarked']])
  embarked_csr =  oe.transform(df[['Embarked']])
  embarked_csr_df = pd.DataFrame(embarked_csr.toarray(), columns = oe.get_feature_names_out())
  df = pd.concat([df, embarked_csr_df], axis=1)

  return df

get_category(train_df_2)

 

  oe.fit(train_df_2[['Embarked']])
  embarked_csr =  oe.transform(df[['Embarked']])
  embarked_csr_df = pd.DataFrame(embarked_csr.toarray(), columns = oe.get_feature_names_out())
  df = pd.concat([df, embarked_csr_df], axis=1)

이 부분을 보시면 'Embarked' 컬럼을 one-hot encoding하고 있는데요,

결과값을 array 형태로 피고 encoding feature 이름을 컬럼명으로하는 데이터프레임을 별도로 만들어 준 후,

df 데이터 프레임에 concat하는 코드입니다.

get_category(train_df_2)로 함수를 돌렸을 때 당연히 concat한 결과값이 출력될 것이라고 생각했으나 그렇지 않았습니다.

 

뭐가 문제인지 확인해보니

get_category 함수의 경우 그 결과값을 train_df_2에 다시 한 번 할당해주어야했습니다.

train_df_2 = get_category(train_df_2)

이렇게 말이죠.

 

get_numeric_sc 함수를 다시 한 번 보겠습니다.

def get_numeric_sc(df):
  from sklearn.preprocessing import StandardScaler, MinMaxScaler
  sd_sc = StandardScaler()
  mm_sc = MinMaxScaler()

  sd_sc.fit(train_df_2[['Fare']])
  df['Fare_sd_sc'] = sd_sc.transform(df[['Fare']])

  mm_sc.fit(train_df_2[['Age', 'Family']])
  df[['Age_mm_sc', 'Family_mm_sc']] = mm_sc.transform(df[['Age', 'Family']])

  return df
get_numeric_sc(train_df_2)

여기서는 transform한 결과값을 df 데이터프레임의 새로운 컬럼에 바로 할당해주고 있습니다.

그렇게 때문에 df를 return했을 때 기존 데이터프레임에 새로운 컬럼들이 추가된 것을 확인할 수 있는 것입니다.

 

def get_category(df):
  from sklearn.preprocessing import LabelEncoder, OneHotEncoder
  le = LabelEncoder()
  le2 = LabelEncoder()
  oe = OneHotEncoder()

  le.fit(train_df_2[['Pclass']])
  df['Pclass_le'] = le.transform(df['Pclass'])

  le2.fit(train_df_2[['Sex']])
  df['Sex_le'] = le2.transform(df['Sex'])

  oe.fit(train_df_2[['Embarked']])
  embarked_csr =  oe.transform(df[['Embarked']])
  embarked_csr_df = pd.DataFrame(embarked_csr.toarray(), columns = oe.get_feature_names_out())
  df = pd.concat([df, embarked_csr_df], axis=1)

  return df

train_df_2 = get_category(train_df_2)

그런데 get_category 함수의 경우

encoding한 Embarked 컬럼값이 포함되어있는 데이터프레임과 기존 df가 concat돼서

새롭게 df라는 데이터프레임이 만들어졌기 때문에

return된 결과 데이터프레임을 train_df_2에 할당해줘야하는 것입니다.

이렇게 이해하면 될 것 같습니다.

concat하는 df의 경우 get_category( )의 소괄호 안에 들어가는 데이터프레임이 반영되지만

concat의 결과값이되는 데이터프레임의 경우 소괄호 안에 들어가는 데이터프레임이 아닌

완전히 새로운 데이터프레임이라고 말이죠.