본문 바로가기

파이썬 머신러닝 완벽가이드

1강-Pandas(2)

본 포스팅은 [파이썬 머신러닝 완벽 가이드 - 권철민]을 참고하여 머신러닝 공부의 목적으로 작성되었습니다!

[스스로 공부하며 작성하는 글이기 때문에 잘못된 내용이 있을 수도 있습니다. 잘못된 부분을 발견하시거나 의견이 있으시면 피드백 부탁드립니다:D]

 

이번 장에서는 DataFrame에서의 데이터 셀렉션 및 필터링을 다뤄보도록 하겠습니다.

처음 접하면 헷갈리기 쉬운 내용이므로 여러 번 반복하여 읽어보시길 추천드립니다!

 

 

  • DataFrame의 [ ] 연산자

Numpy에서는 2차원 데이터에서 데이터를 추출할 때 ndarray [0,0]과 같이 ndarray바로 뒤 [ ] 연산자 안에 행의 위치, 열의 위치, 슬라이싱 범위 등을 지정해 데이터를 가져왔습니다. 

하지만 DataFrame 에서는 별도의 ix[ ], iloc[ ], loc[ ] 연산자를 이용해 데이터를 추출합니다.

 

그렇다면 DataFrame 바로 뒤 [ ] 연산자는 어떤 상황에서 사용할까요?

주로 1. [ ] 안에 특정 칼럼명을 지정해 칼럼 지정 연산에 사용하거나 2. 불린 인덱스의 용도로 사용합니다.

 

참고) DataFrame 바로 뒤 [ ] 연산자에 인덱스로 변환 가능한 표현식(=슬라이싱), 예를 들어 [2:4], [0:3]도 가능은 하나 사용하지 않는 것이 좋다고 합니다!

 

1. 칼럼명 지정

2. 불린 인덱싱

 

 

그럼 본격적으로 DataFrame의 데이터 추출 연산자인 ix[ ], iloc[ ], loc[ ]에 대해 알아보도록 하겠습니다.

 

 

  • ix[ ]

ix[ ]는 현재 사용되고 있는 연산자이긴 하나 혼동을 주는 부분이 있어 향후 사라질 예정이라고 합니다. 하지만 iloc[ ], loc[ ]에 대한 이해를 돕기 위해 살펴보도록 하겠습니다.

 

먼저 명칭(label) 기반 인덱싱과 위치(position) 기반 인덱싱에 대해 알아야 합니다.

아래의 예제를 보시면 쉽게 이해 되실겁니다.

 

맨 처음 행,열의 위치는 0부터 시작합니다.

 

3번째 예에서 알 수 있듯이 ix[ ] 는 명칭 기반 인덱싱과 위치 기반 인덱싱을 모두 제공합니다.

이는 인덱스가 다음과 같이 integer형인 경우 혼선을 줄 수 있습니다.

(저번 장의 reset_index를 이용하여 정수형의 새로운 index를 만들어 주었습니다. 헷갈리시는 분은 저번 장을 참고해 주세요!)

앞서 말씀드렸듯이 ix[ ]는 명칭 기반 인덱싱과 위치 기반 인덱싱을 모두 제공한다 했습니다.

 

그렇다면 data_df_reset.ix[1,1] 의 결과는 무엇일까요? 명칭 기반 인덱싱의 결과인 'Chulmin'일까요? 아니면 위치 기반 인덱싱의 결과인 'Eunkyung'일까요?

 

-정답은 명칭 기반 인덱싱 'Chulmin'입니다!

위와 같이 인덱스가 Integer인 경우에는 명칭 기반 인덱싱이 우선한다 생각하면 됩니다.

(참고 : data_df_reset.ix [0,1]의 경우는 오류를 반환합니다. 명칭 기반 인덱싱이기 때문에 index값이 0인 key를 찾을 수 없기 때문입니다.)

 

하지만 이러한 방식은 사용할 때 헷갈리기 쉽습니다.

이러한 혼선을 막기 위해 위치 기반 인덱싱인 iloc[ ] 와 명칭 기반 인덱싱인 loc[ ] 를 구분하여 사용하게 되었습니다.

 

 

  • iloc[ ]

iloc[ ]는 위치 기반 인덱싱으로 행과 열 값으로 Integer 또는 Integer형의 슬라이싱 팬시 리스트 값을 입력해줘야 합니다.

Integer 형이 아닌 명칭을 입력하면 오류가 납니다. 

 

  • loc[ ]

loc[ ]는 명칭 기반으로 데이터를 추출합니다.

loc [ ]에서 슬라이싱 기호 ':'를 적용할 때 유의할 점이 있습니다.

일반적으로 슬라이싱 기호를 적용하면, 시작 값부터 (종료 값 -1)의 범위를 의미합니다. 

하지만 loc[ ]에서는 슬라이싱 기호를 적용하면, 종료 값까지 포함하는 범위를 의미합니다. 이는 명칭 기반 인덱싱이기 때문인데 명칭은 숫자 형이 아닐 수 있기에 -1을 할 수가 없습니다.

이는 ix[ ]를 명칭 기반으로 사용할 때도 마찬가지입니다.

 

 

 

  • 불린 인덱싱

불린 인덱싱은 넘파이에서 언급했듯이 원하는 조건을 만족시키는 값들을 추출해내는 방식입니다. 

불린 인덱싱은 [ ], ix[ ], loc[ ]에서 공통으로 지원됩니다.

(iloc[ ]는 정수형 값이 아닌 불린 값에 대해서는 지원하지 않기 때문에 불린 인덱싱이 지원되지 않습니다.)

 

1. [ ] 연산자 이용

titanic_df라는 DataFrame에서 'Age'>60인 행들로 이루어진 DataFrame을 먼저 뽑아내고,

             => titanic_df[titanic_df['Age'>60]

이 DataFrame에서 다시 [ ] 연산자를 이용하여 원하는 칼럼들을 추출합니다.

            => titanic_df[titanic_df['Age'>60]['Name','Age']

 

 

2. loc [ ] 연산자 이용

행 자리에 불린 인덱싱을 이용하여 조건문에 대하여 True인 행들만 먼저 뽑아내고,

원하는 칼럼명을 입력하여 칼럼을 뽑아냅니다. ix[ ] 방식도 이와 동일합니다.

 

여러 조건을 동시에 적용할 수도 있습니다.

and 조건 => &   

or 조건   => |

Not 조건 => ~

 

 

 

이제 DataFrame의 다양한 연산 함수에 대해 알아보겠습니다.

 

  • sort_values()

DataFrame과 Series의 정렬을 위해 사용하는 메서드입니다. 

주요 입력 파라미터로는 by, ascending, inplace가 있습니다.

 

1. by는 정렬을 수행할 특정 칼럼을 입력하고,

2. ascending = True 이면 오름차순으로, False 면 내림차순입니다. 디폴트는 True입니다.

3 inplace = False는 원본 데이터를 변경하지 않고 정렬된 DataFrame을 반환하며,

                True는 반환 값이 None이며 원본 데이터를 변경합니다. 디폴트는 False입니다.

 

 

  • aggregation

DataFrame에 min(), max(), count(), sum() 과 같은 함수를 적용할 수 있습니다.

 

-DataFrame에 바로 aggregation 함수를 적용하면 모든 칼럼에 함수를 적용합니다.

-특정 칼럼을 추출하여 aggregation 함수를 적용할 수도 있습니다.

 

 

  • groupby()

-입력 파라미터 by에 칼럼을 입력하여 대상 칼럼으로 groupby 합니다.

 

-groupby 된 객체에서 원하는 특정 칼럼만 선택하여 함수를 적용할 수 있습니다.

 

-한 칼럼에 대하여 agg()를 이용하여 여러 개의 aggregation 함수를 적용할 수 있습니다.

 

-여러 개의 칼럼에 서로 다른 함수를 적용하고 싶으면 딕셔너리 형태로 agg( )에 입력해주면 됩니다.

 

 

  • isna(), fillna()

-isna()

isna()는 데이터가 NaN인지 아닌지를 알려주는 함수입니다. NaN이란 결손 데이터로 칼럼에 값이 없는 것을 의미합니다.

칼럼에 값이 비었다면, NaN이라면 True(1),

          값이 있다면 False(0)로 표시합니다.

따라서 isna()에 sum() 함수를 추가하면 칼럼 별 NaN 값의 개수를 구할 수 있습니다.

 

 

-fillna()

isna()를 통해 확인한 결손 데이터를 fillna()를 이용해 다른 값으로 대체할 수 있습니다.

 

여기서 주의할 점은 inplace=True로 설정해줘야 실제 데이터 세트가 변경됩니다.

다른 방법으로는 반환 값을 다시 원본 칼럼에 할당해주는 것입니다.

 

 

  • apply.(lambda x : f(x))

apply 함수에 lambda 식을 결합해 DataFrame이나 Series의 레코드 별로 데이터를 가공합니다.

 

먼저 lambda 식이란 파이썬에서 함수의 선언과 처리를 한 줄의 식으로 간단하게 변환하는 식입니다.

아래의 예제를 통해 살펴보겠습니다.

lambda x : x**2에서 ':'기호를 기준으로 왼쪽에는 입력 인자를, 오른쪽에는 반환 값을 입력해줍니다.

 

DataFrame에서 lambda 식을 어떻게 활용하는지 살펴보겠습니다.

DataFrame에서 [ ] 연산자를 이용해 'Name'칼럼을 따로 뽑아내고, apply와 lambda 식을 적용하여 'Name_len'이라는 새로운 칼럼을 만들어냈습니다. 

lambda 식에는 if else 절을 사용하여 조금 더 복잡한 가공을 수행할 수도 있습니다.

여기서 주의할 점은 lambda 식의 ':' 기호 오른쪽에 반환 값이 있어야 하므로 반환 값을 먼저 입력한 후 뒤에 조건문을 입력해야 한다는 것입니다.

하지만 else if는 지원하지 않으므로 if 절과 else 절을 중첩하여 사용해야 합니다.

만약 x <=15 'Child', 15 <x <=60 'Adult', x>60 'Elderly' 조건을 적용하려면 다음과 같아야 합니다.

else( ) 절 안에서도 반환 값인 'Adult'가 먼저 나오는 것을 주의해야 합니다.

이러한 방식을 사용하면 else if 조건이 많아야 하는 경우에는 식이 복잡해지는 문제가 생길 수 있습니다.

이런 경우에는 별도의 함수를 만들고 lambda 식을 적용하는 것이 낫습니다.

 

지금까지 데이터를 전처리하는데 중요한 패키지인 판다스에 대해 알아보았습니다.

다음 장부터는 다양한 라이브러리를 이용하여 본격적으로 머신러닝을 다뤄보도록 하겠습니다.