AI 공부 저장소
[파이썬 머신러닝 완벽가이드] Chap01-2. pandas 라이브러리 3 본문
[파이썬 머신러닝 완벽가이드] Chap01-2. pandas 라이브러리 3
aiclaudev 2022. 1. 2. 18:41
- 본 글은 파이썬 머신러닝 완벽 가이드 (권철민 지음)을 공부하며 내용을 추가한 정리글입니다. 개인 공부를 위해 만들었으며, 만약 문제가 발생할 시 글을 비공개로 전환함을 알립니다.
[1] DataFrame, Series의 정렬 - sort_values( )
titanic_sorted = titanic_df.sort_values(by=['Name'])
titanic_sorted.head()
titanic_sorted2 = titanic_df.sort_values(by=['Pclass', 'Name'], ascending = False)
titanic_sorted2.head()
위 예시 코드를 봐도 어떻게 사용해야하는지 쉽게 알 수 있을겁니다. 선택한 Column의 값을 기준으로 DataFrame을 정렬합니다!
ㆍby : 어떤 Column의 데이터를 기준으로 정렬할 지 명시해주기 위한 parameter입니다. 리스트 형으로 전달해주어야 해요! 만약 1순위는 'Pclass', 2순위는 'Name'으로 정렬하고 싶다면, 순서대로 ['Pclass', 'Name']을 전달해주면 됩니다.
ㆍascending : 오름차순으로 정렬할 지, 내림차순으로 정렬할 지 선택하기 위한 parameter입니다. 기본값은 오름차순이며, False로 설정한다면 내림차순으로 정렬됩니다!
ㆍinplace : 이제는 아주 익숙한 parameter죠. 원본 데이터프레임 자체를 변화시킬 지, 아니면 변화된 데이터 프레임을 반환할 지 정하기 위한 부분입니다. True면 원본 데이터 프레임을 변화시키고, False면 변화된 데이터 프레임을 반환합니다!
[2] Aggregation 함수
titanic_df.count()
PassengerId 891
Survived 891
Pclass 891
Name 891
Sex 891
Age 714
SibSp 891
Parch 891
Ticket 891
Fare 891
Cabin 204
Embarked 889
dtype: int64
titanic_df[['Age', 'Fare']].mean()
Age 29.699118
Fare 32.204208
dtype: float64
이번에 다룰 것은, Aggregation함수입니다. Aggregation함수란, min( ) max( ) sum( ) count( ) 등의 함수를 일컫는 용어입니다. 한 가지 특징은, DataFrame.mean( )과 같이 DataFrame에 Aggregation함수를 적용할 시 모든 Column에 대해 연산을 수행한다는 것 입니다! 만약 특정 컬럼들에 대해서만 Aggregation함수를 적용하고 싶다면, 위 예시코드처럼 여러 컬럼에 먼저 접근한 후, 함수를 적용해주면 됩니다.
[3] groupby( )의 적용!
titanic_groupby = titanic_df.groupby(by = 'Pclass')
print(type(titanic_groupby))
print('\n')
titanic_groupby = titanic_df.groupby(by = 'Pclass').count()
titanic_groupby
groupby란, 특정 Column을 기준으로 그룹을 형성하는 것을 의미합니다! 보통 Aggregation함수와 함께 사용됩니다.
예를 들어, 위 예시의 titanic_groupby = titanic_df.groupby(by = 'Pclass').count( )를 해석해보면, 'Pclass로 그룹을 묶은 후, Pclass의 각 데이터에 해당하는 row의 개수를 세줘!'라고 할 수 있겠네요. (참고로, by는 꼭 안써도 됩니다.)
한 가지 예시를 더 들면, row가 총 100개인 DataFrame에 'Age'라는 나이가 10-20대, 20-30대, 30-40대인지를 담은 Column이 있다고 합시다. 이 때 titanic_df.groupby(by='Age').count( )를 적용하면, '10-20대 : 40명, 20-30대 : 30명, 30-40대 : 30명' 과 같은 정보가 나온다는 것이죠!
데이터프레임에 groupby를 적용하였을 때 return한 객체는 DataFrameGroupBy라는 또다른 형태의 DataFrame입니다. 이에 주의합시다!
titanic_groupby = titanic_df.groupby('Pclass')[['PassengerId', 'Survived']].count()
titanic_groupby
만약, 몇몇개의 Column에 대해서만 연산을 수행하고 싶다면 위와 같이 하면 됩니다.
'Pclass'의 데이터에 따라 그룹을 묶고난 후, [ ]를 통해 특정 컬럼에 접근한 뒤 Aggregation함수를 적용하면 됩니다!
titanic_groupby = titanic_df.groupby('Pclass')['Age'].agg([max, min])
titanic_groupby
하나의 Column에 대해 두 가지 Aggeregation함수를 적용시켜야할 때도 있겠죠? 그 땐 위 코드와 같이 DataFrameGroupBy객체의 agg메소드를 활용하면 됩니다. agg( )내에 리스트 형태의 Aggregation 함수 명을 입력하면 끝입니다!
agg_format = {'Age' : 'max', 'SibSp' : 'sum', 'Fare' : 'mean'}
titanic_groupby = titanic_df.groupby('Pclass').agg(agg_format)
titanic_groupby
groupby( )의 마지막 활용방법 입니다. 여러 컬럼에 대해 각각 다른 Aggregation함수를 적용시키고 싶을 수도 있어요. 이 때 DataFrameGroupBy의 agg를 사용할 수 있습니다. 이 때, dictionary를 통해 '어느 Column에 대해 어느 Aggregation 함수를 적용할지'를 명시하면 됩니다. 이 과정에서 '어느 Column을 사용할 건지'를 알려주기에, [ ]로 특정 Column을 지정해줄 필요는 전혀 없습니다!
[4] 결손 데이터 처리하기! DataFrame.isna( )와 DataFrame.fillna( )
결손 데이터란, 값이 없는, 즉 NULL인 데이터를 의미하는데요. 데이터 분석에 들어가기 전 이러한 결손 데이터를 삭제하거나 특정 값으로 설정하는 등의 과정은 필수랍니다! 판다스에서 결손데이터는, 넘파이의 NaN으로 표시합니다.
또한, NaN은 평균, 총합 등의 함수 연산 시에는 자동으로 제외됩니다. 만약 100개의 데이터 중 10개의 NaN이 있다면, 평균은 결손 데이터가 아닌 나머지 90개의 평균이 되는 것이죠.
print(titanic_df.isna().sum())
titanic_df.isna()
DataFrame.isna( )를 통해 어느 곳의 데이터가 결손 데이터인지 확인할 수 있습니다! 결손 데이터라면 True, 아니면 False로 채워져있는 것을 확인할 수 있죠. 결손 데이터의 개수는 isna( )에 sum( )을 적용함으로써 알 수 있습니다. 프로그래밍을 겪어보신 분이라면 보통의 프로그래밍 언어에서 False는 0, True는 1이라는 것 아시죠? 이러한 원리를 통해 결손 데이터의 총 개수를 확인할 수 있는 것이라고 생각하시면 되겠네요!
titanic_df = pd.read_csv("C:/Users/82102/Desktop/sw/PythonMLGuide/pandas/titanic_train.csv")
titanic_df['Cabin'] = titanic_df['Cabin'].fillna('C000')
titanic_df['Age']= titanic_df['Age'].fillna(titanic_df['Age'].mean()) # Age컬럼의 결손 데이터를 mean값으로 채운다
titanic_df['Embarked'] = titanic_df['Embarked'].fillna('S')
titanic_df.isna().sum()
DataFrame.isna( )를 통해 결손 데이터를 확인했으니, DataFrame.fillna( )를 통해 결손 데이터에 값을 넣어봅시다!
fillna( )는 이름만 봐도 알 수 있듯이, 값이 NaN인 데이터에 어떠한 값을 넣어주는 것이에요. 위 예시 코드에서 Age 컬럼에 대해 결손 데이터를 처리한 부분을 보시면, 평균으로 값을 할당했음을 볼 수 있는데요, Continuous한 Numeric 데이터에는 보통 평균을 많이 넣습니다. (그래야 해당 컬럼의 전체 평균은 변화하지 않거든요!)
추가로, inplace 파라미터를 추가할 수 있습니다. inplace = True로 설정 시 원본데이터프레임이 그대로 바뀝니다.
마지막으로, DataFrame.isna( ).sum( )을 통해 결손 데이터가 남아있는지 확인할 수 있습니다!
[5] apply lambda 식으로 데이터를 가공하자!
titanic_df['Name_len'] = titanic_df['Name'].apply(lambda x : len(x))
titanic_df[['Name', 'Name_len']].head()
apply lambda를 통해 데이터를 가공하는 것은 굉장히 흔한 일입니다. 특히 새로운 Column 등을 추가할 때 말이죠!
앞서, DataFrame['컬럼명']으로 새로운 컬럼을 추가할 때, 컬럼 간 연산을 사용했었습니다! 하지만, 단순한 연산만으로 컬럼을 추가할 수 없는 경우가 분명 생기죠. 이럴땐 위와 같이 lambda 함수 형식으로 컬럼을 추가할 수 있습니다!
전체적인 apply lambda의 형태는 아래와 같습니다.
DataFrame['Column'].apply(lambda x : func(x))
입력 반환
기본적인 형태를 숙지한 후 따라오시면 좋겠습니다!
titanic_df['Child_Adult'] = titanic_df['Age'].apply(lambda x : 'Child' if x <= 15 else 'Adult')
titanic_df[['Age', 'Child_Adult']].head(8)
이번엔 apply lambda에 if / else문을 적용했네요! 우리가 평소 알던 if / else문과는 형태가 약간 상이하죠?
if문에서의 반환형은 if보다 앞에 와야합니다. else문은 평소에 쓰던대로 써주시면 돼요! (else 뒤에 반환)
코드를 해석해보면, 입력받은 x가 15이하이면 Child를 반환하고, 그렇지 않으면 Adult로 반환했네요! 이러한 과정으로 새롭게 추가된 Column인 Child_Adult는 위 표와 같습니다.
titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : 'Child' if x <= 15 else ('Adult' if x <= 60 else 'Elderly'))
titanic_df['Age_cat'].value_counts()
Age의 카테고리를 더욱 세분화 해보았습니다. 15세 이하는 Child, 15~60세 이하는 Adult, 60세를 넘을 경우엔 Elderly로 설정하였네요. 위 코드를 보면 조금 복잡해 보입니다. 그 이유는 if / elif / else 문을 사용하지 않았기 때문입니다. 사용하지 않은 이유는, apply lambda 식에서 elif는 지원되지 않습니다ㅎㅎ.. 따라서, else문 안에 if / else문을 다시 사용하는 방식으로 if / elif / else를 구현해야 합니다. else문 안에서도 역시, 반환형은 if 앞에 위치해야한다는 것 잊지 맙시다!
def get_category(age) :
cat = ''
if age <= 5 : cat = 'Baby'
elif age <= 12 : cat = 'Child'
elif age <= 18 : cat = 'Teenager'
elif age <= 25 : cat = 'Student'
elif age <= 35 : cat = 'Young Adult'
elif age <= 60 : cat = 'Adult'
else : cat = "Elderly"
return cat
titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : get_category(x))
titanic_df['Age_cat'].value_counts()
앞서 설명한, apply lambda 식 내에서의 if / else문 사용은 조건을 세분화 시키는 것이 굉장히 어렵다는 것 느껴지시죠?
이를 보완하기 위해, 사용자 정의 함수를 사용할 수 있습니다! apply lambda 식 내에서 반환이 위치하는 곳에 임의의 사용자 정의 함수를 사용하면 되겠네요!
if / else 문처럼 조건이 2개여서 apply lambda식을 간단히 사용할 수 있는 경우가 아닌 이상, 위 처럼 사용자 정의 함수를 이용하는 것이 더욱 가독성이 높아보입니다.
- 본 글은 파이썬 머신러닝 완벽 가이드 (권철민 지음)을 공부하며 내용을 추가한 정리글입니다. 개인 공부를 위해 만들었으며, 만약 문제가 발생할 시 글을 비공개로 전환함을 알립니다.
'Artificial Intelligence > [파이썬 머신러닝 완벽가이드]' 카테고리의 다른 글
[파이썬 머신러닝 완벽가이드] Chap02-2. 사이킷런 기반 프레임워크 익히기 (0) | 2022.01.06 |
---|---|
[파이썬 머신러닝 완벽가이드] Chap02-1. 사이킷런 - 붓꽃 품종 예측하기 (0) | 2022.01.02 |
[파이썬 머신러닝 완벽가이드] Chap01-2. pandas 라이브러리 2 (0) | 2021.12.31 |
[파이썬 머신러닝 완벽가이드] Chap01-2. pandas 라이브러리 1 (0) | 2021.12.30 |
[파이썬 머신러닝 완벽가이드] Chap01-1. numpy 라이브러리 (0) | 2021.12.29 |