반응형

깃허브: https://github.com/PSLeon24/Research_python/blob/main/pandas/pandas3.ipynb

 

이전 포스팅에서는 '[Pandas 입문] 데이터프레임의 부분집합을 어떻게 선택할 수 있을까?(https://psleon.tistory.com/61)'에 대해 학습하며 데이터프레임에서 시리즈만 또는 일부 데이터프레임을 추출하거나 조건에 맞게 추출하는 다양한 실습을 해보았다.

처음에는 공식문서 마지막 부분에 loc와 iloc가 있어 한 포스팅에 모두 기록하고자 하였으나, 이전에 판다스를 학습할 때에도 loc와 iloc가 헷갈렸던 기억이 있어 본 포스팅을 통해 확실히 짚고 넘어가고자 한다.

 

먼저 loc와 iloc는 무엇의 약자인지 알고 시작하는 것이 좋다.

  • loc는 location의 약자이다. 이 방법은 DataFrame의 행 또는 열의 이름(label)이나 Boolean array를 통해 특정 값을 추출하는 방법이다.
  • iloc는 integer location의 약자이다. 즉, DataFrame의 row나 column의 순서를 나타내는 정수(integer)를 통해서 특정 값을 추출하는 방법이다.

 

loc

df.loc['행 인덱싱 값', '열 인덱싱 값']

이번 실습 또한 Titanic(타이타닉) 데이터로 실습하고자 한다. 위 데이터들 중에서 'Name'이라는 특정 column만 추출할려면 어떻게 해야 할까? 아래와 같이 단순히 titanic['Name']으로 추출할 수 있다.

이를 loc를 통해 추출해보자. '행의 인덱스 값'은 ''으로 두면 될까?

오류가 발생한다. 그러면 빈 공란으로 둬보자.

이 방법 또한 문법상 오류가 출력된다.

사실, 전체 행에 대해서 특정 컬럼을 추출할 때에는 콜론(:)을 사용해줘야 한다.

그렇다면 콜론(:)의 의미는 무엇일까? 바로 전체라는 뜻이다. 이를 아래의 그림을 통해 증명하겠다.

타이타닉 데이터의 전체 행과 열이 추출된 것으로 콜론은 전체를 의미한다는 것을 확인할 수 있었다.

이제 범위를 축소시켜서 0~4 행까지의 데이터 중에서 Age 열만 추출하려면 어떻게 할 수 있을까?

다시 문법을 생각해보자. df.loc['행 인덱스 값', '열 인덱스 값']

그러면 titanic.loc['0~4', 'Age'] 일까?

아니다. 0~4까지 추출하기 위해서 파이썬에서의 슬라이싱과 유사하게 '0:4'와 같이 표현하면 된다.

여기서 필자는 '유사'라는 단어를 사용했다. 먼저 아래의 그림을 한번 유심히 살펴보자.

a는 [0, 1, 2, 3, 4, 5]라는 값으로 초기화된 리스트를 생성하고 0:5로 슬라이싱을 한 것이고, b는 [0, 1, 2, 3, 4, 5]의 값으로 판다스의 시리즈로 만들어 준 후 loc를 통해 0:5까지 슬라이싱을 한 것이다.

전자의 경우 0~4까지만 출력이 되었으나, 후자의 경우 0~5까지 모두 출력이 된다는 차이점이 있다.

즉, 파이썬의 슬라이싱 같은 경우 [start:end]와 같은 형태라면 start~end-1 까지만 출력이 되는데, 판다스의 loc에서는 start~end까지라는 점이다.

 

여튼, 다시 본론으로 돌아와서 0~4 행까지의 데이터 중에서 Age 열만 추출하고자 한다면 아래와 같이 추출 할 수 있을 것이다.

  • titanic.loc[0:4, 'Age']

그런데 매번 하나의 열만 추출하고 싶지는 않을 것이다. 2개 이상의 열을 추출하고자 하거나, 또는 행 인덱스의 값이 연속된 정수로 이루어져 슬라이싱을 할 수 있는 경우가 아닐 때는 어떻게 할까?

바로 리스트의 형태로 대괄호([])로 묶어서 추출하면 된다. 아래의 예를 통해 살펴보자.

0~4행의 데이터 중 Name 열과 Age 열을 추출하기 위해서 열 인덱스 값을 ['Name', 'Age']로 묶어서 추출했음을 확인할 수 있다.

 

iloc

df.loc[행 인덱스, 열 인덱스]

앞서 살펴본 loc는 행이나 열의 인덱스 값을 직접 써줌으로써 사람이 읽기 좋은 방식으로 데이터에 접근하는 방식이었다.

이번에 살펴볼 iloc는 컴퓨터가 읽기 좋은 정수로 데이터가 존재하는 위치에 접근하는 방식이라고 생각하면 편하게 이해할 수 있다.

이를 위해 먼저 기본적인 'df.loc[행 인덱스, 열 인덱스]' 이 구조는 외우도록 하자.

 

자, 먼저 임의의 값들을 넣어 값의 변화부터 살펴보자.

titanic.iloc[0]을 입력해주니 0번째 행의 객체가 반환되었음을 확인할 수 있다.

이때, titanic 데이터에서 0행 0열의 값은 무엇일까? 바로 PassengerId의 1 값이다.

titanic.iloc[0, 0]을 하면 1이 출력됨을 알 수 있다. 이 방식이 맞는지 확인해보기 위해서 0행의 3열에 해당하는 Name 열을 추출해보자.(단, 1행, 1열부터 세지 않고 0행 0열부터라고 가정한다.)

titanic.iloc[0, 3]을 입력하였더니 정상적으로 'Braund, Mr. Owen Harris'가 출력되는 것을 확인할 수 있다.

 

Pandas의 concat() 함수를 사용하면 아래와 같이 특정 행이나 열부분의 데이터만 합쳐서 나타낼 수도 있다.

다만, 위 그림을 유심히 살펴보면 무엇인가 다른 점이 느껴질 것이다.

5초만 더 고민해보자. 그래도 잘 모르겠으면 아래 그림으로 더 쉽게 생각해보자.

그렇다. titanic.loc[2:4, :]를 입력했으면 2~4행까지의 모든 열이 다 출력될텐데 titanic.iloc[2:4]를 입력하니 2~3행까지만 출력이 되었다. 그러면 iloc는 파이썬의 슬라이싱 기법과 동일하다고 보면 된다.

왜 다를까? loc는 인덱스의 값을 넣는 것이고, iloc는 인덱스를 넣는 것이기 때문이다.

그렇다면, loc의 경우 문자열을 슬라이싱 할 수도 있을 것이다. 아래의 예를 통해 살펴보자.

0~4행 중 Age열부터 Parch열까지 추출하는데 성공했다.

 

오늘 살펴본 loc와 iloc는 처음 사용할 경우 비슷하다고 느껴 헷갈리기도 하고 어려움도 느낀다.

다만, 우리는 시험을 치기 위한 학습이 아닌 데이터분석을 위한 도구를 익히는 것이므로 무한 반복을 통해 손에 익숙해지면 어느 순간 데이터를 보자마자 어떤식으로 접근하면 된다는 '직관'이 생긴다.

따라서, 어렵더라도 반복, 반복 또 반복해서 직접 타이핑하며 학습하자.