본문 바로가기

Programming/Data mining

6. Pandas 심화 (Merge(), Pandorable code)

Coursera.org 에서 Michigan University의 Applied Data Science with Python의 강의를 토대로 정리한 내용입니다.

이제까지 간단한 파이썬과 Numpy 그리고 Pandas를 활용한 데이터마이닝방법에 대해서 알아보았는데요, 이제부터는 DataFrame을 합치거나 그룹핑 하는 등 조금 더 심화적인 데이터를 다루는 함수에 대해서 살펴보도록 합시다.

먼저 소개한 대로 DataFrame을 합치는 것 부터 해볼까요?

staff_df = pd.DataFrame([{'Name': 'Kelly', 'Role': 'Director of HR'},
                         {'Name': 'Sally', 'Role': 'Course liasion'},
                         {'Name': 'James', 'Role': 'Grader'}])
staff_df = staff_df.set_index('Name')

student_df = pd.DataFrame([{'Name': 'James', 'School': 'Business'},
                           {'Name': 'Mike', 'School': 'Law'},
                           {'Name': 'Sally', 'School': 'Engineering'}])
student_df = student_df.set_index('Name')

pd.merge(staff_df, student_df, how='outer', left_index=True, right_index=True)

#staff와 student 두개의 데이터프레임을 합칠 때에는 .merge()라는 함수를 사용합니다.
#.merge()의 괄호 안에는 어떤 데이터프레임을 합칠지에 대한 파라미터 설정과 How라는 attribute를 설정해주는데요.
#how = 'outer'로 설정 시 합집합, 'inner'로 설정 시 교집합,
#'left'나 'right'로 설정 시 한 쪽의 index를 중심으로 데이터를 합친다고 생각하시면 된답니다.
#left_index나 right_index는 각 데이터프레임의 index를 그대로 사용하고자 할 때 True.
#재설정을 원할 시에는 아래와 같이 left_on, right_on attribute에 index를 할당해주면 됩니다.

pd.merge(staff_df, student_df, how='left', left_on='Name', right_on='Name')

pd.merge(staff_df, student_df, how='inner', left_on=['First Name','Last Name'], right_on=['First Name','Last Name'])
#이렇게 index를 두개로 할당해줄수도 있어요.


 

이번에는 꽤나 재밌는 주제를 다뤄볼까요?
바로 Pandas만의 관용적인 프로그래밍들인데요, 이러한 특성을 지닌 코드를 우리는 판다스러운 코드, pandorable code라고 부른답니다.
예시로 살펴보죠.

(df.where(df['SUMLEV']==50)
    .dropna()
    .set_index(['STNAME','CTYNAME'])
    .rename(columns={'ESTIMATESBASE2010': 'Estimates Base 2010'}))
    
#()안에 줄바꿈을 활용하여 굳이 반복적으로 함수를 호출하는 것이 아닌 한번에 효율적으로 함수적용이 가능하군요.

df.rename(columns={'ESTIMATESBASE2010': 'Estimates Base 2010'})

#columns의 index를 위와 같은 코드로 재설정할수도 있구요.

import numpy as np
def min_max(row):
    data = row[['POPESTIMATE2010',
                'POPESTIMATE2011',
                'POPESTIMATE2012',
                'POPESTIMATE2013',
                'POPESTIMATE2014',
                'POPESTIMATE2015']]
    return pd.Series({'min': np.min(data), 'max': np.max(data)})

#이렇게 numpy를 활용하여 5개의 columns에서 최솟값과 최댓값만을 따로 저장하는 함수를 만든 뒤,

df.apply(min_max, axis=1)
#.apply()함수를 통해서 간단하게 적용하기도 하네요.
#여기서 axis는 0으로 설정시 행 기준으로 함수를 적용하며, 1로 설정시 열 기준으로 함수를 적용하게 됩니다.

def min_max(row):
    data = row[['POPESTIMATE2010',
                'POPESTIMATE2011',
                'POPESTIMATE2012',
                'POPESTIMATE2013',
                'POPESTIMATE2014',
                'POPESTIMATE2015']]
    row['max'] = np.max(data)
    row['min'] = np.min(data)
    return row
df.apply(min_max, axis=1)

#마찬가지의 코드를 위와 같은 방법으로도 사용할 수 있군요.
#단, 위 코드와의 차이점은 row라는 데이터프레임에 max와 min 열을 추가한 형태가 되겠네요.

rows = ['POPESTIMATE2010',
        'POPESTIMATE2011',
        'POPESTIMATE2012',
        'POPESTIMATE2013',
        'POPESTIMATE2014',
        'POPESTIMATE2015']
df.apply(lambda x: np.max(x[rows]), axis=1)

#lambda함수를 활용해서 따로 함수를 설정하지 않고 바로 값을 호출해볼수도 있답니다.