ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Chapter.02-2 데이터 추출하기
    Do it! 판다스 입문 2022. 6. 12. 14:09

    지금까지 데이터프레임의 크기와 자료형을 살펴보는 방법에 대해 알아보았습니다. 앞에서 head 메서드를 이용해 데이터프레임에서 가장 앞에 있는 5개의 데이터를 추출하여 출력했던 것을 기억하나요? 이번에는 데이터프레임에서 데이터를 열 단위로 추출하는 방법과 행 단위로 추출하는 방법을 알아보겠습니다. 먼저 열 단위로 데이터를 추출하는 방법을 알아보겠습니다.

     

     

    열 단위 데이터 추출하기

    데이터프레임에서 데이터를 열 단위로 추출하려면 대괄호와 열 이름을 사용해야 합니다. 이때 열 이름은 꼭 작은따옴표를 사용해서 지정해야 하고 추출한 열은 변수에 저장해서 사용할 수도 있습니다. 이때 1개의 열만 추출하면 시리즈를 얻을 수 있고 2개 이상의 열을 추출하면 데이터프레임을 얻을 수 있습니다.

     

     

     

    열 단위로 데이터 추출하기

    1. 다음은 데이터프레임(df)에서 열 이름이 country인 열을 추출하여 country_df에 저장한 것입니다. type 메서드를 사용하면 country_df에 저장된 데이터의 자료형이 시리즈라는 것을 확인할 수 있습니다. 시리즈도 head, tail 메서드를 가지고 있기 때문에 head, tail 메서드로 가장 앞이나 뒤에 있는 5개의 데이터를 출력할 수 있습니다.

    country_df = df['country']

    print(type(country_df))

    <class 'pandas.core.series.Series'>

    print(country_df.head( ))

    0     Afghnistan
    1     Afghnistan
    2     Afghnistan
    3     Afghnistan
    4     Afghnistan
    Name: country, dtype: object

    print(country_df.tail( ))

    1699     Zimbabwe
    1700     Zimbabwe
    1701     Zimbabwe
    1702     Zimbabwe
    1703     Zimbabwe
    Name: country, dtype: object

     

    2. 리스트에 열 이름을 전달하면 여러 개의 열을 한 번에 추출할 수 있습니다. 다음은 열 이름이 country, continent, year인 열을 추출하여 변수 subset에 저장한 것입니다. 이때 1개의 열이 아니라 2개 이상의 열을 추출했기 때문에 시리즈가 아니라 데이터프레임을 얻을 수 있습니다.

    subset = df[['country', 'continent', 'year']]
    print(type(subset))

    <class 'pandas.core.frame.DataFrame'>

    print(subset.head( ))
               country  continent    year
    0  Afghanistan          Asia   1952
    1  Afghanistan          Asia   1957
    2  Afghanistan          Asia   1965
    3  Afghanistan          Asia   1967
    4  Afghanistan          Asia   1972

    print(subset.tail( ))
                   country  continent   year
    1699  Zimbabwe       Africa   1987
    1700  Zimbabwe       Africa   1992
    1701  Zimbabwe       Africa   1997
    1702  Zimbabwe       Africa   2002
    1703  Zimbabwe       Africa   2007

     

     

     

     

    행 단위 데이터 추출하기

    이번에는 데이터를 행 단위로 추출하는 방법에 대해 알아보겠습니다. 데이터를 행 단위로 추출하려면 loc, iloc 속성을 사용해야 합니다. 다음은 두 속성을 간단하게 정리한 표입니다.

    속성 설명
    loc 인덱스를 기준으로 행 데이터 추출
    iloc 행 번호를 기준으로 행 데이터 추출

     

    표의 설명을 보면 인덱스와 행 번호라는 것이 있습니다. 파이썬을 공부한 독자라면 리스트 같은 자료형에 저장된 데이터의 순서를 인덱스라고 알고 있을 것입니다. 하지만 판다스에서는 이런 개념을 행 번호라고 부릅니다(판다스에서 인덱스는 조금 다른 의미로 사용됩니다). 다음 예제를 실습하면서 판다스에서 말하는 인덱스와 행 번호가 무엇인지 알아보겠습니다.

     

     

     

     

    인덱스와 행 번호 개념 알아보기

    다음은 갭마인더 데이터 집합을 불러온 다음 head 메서드를 실행한 결과입니다.

               country  continent    year    lifeExp            pop    gdpPercap
    0  Afghanistan          Asia   1952    28.801     8425333   779.445314
    1  Afghanistan          Asia   1957    30.332     9240934   820.853030
    2  Afghanistan          Asia   1965    31.997   10267083   853.100710
    3  Afghanistan          Asia   1967    34.020   11537966   836.197138
    4  Afghanistan          Asia   1972    36.088   13079460   739.981106

     

    왼쪽의 번호가 보이시나요? 바로 이것이 인덱스입니다. 인덱스는 보통 0부터 시작하지만 행 데이터가 추가, 삭제되면 언제든지 변할 수 있으며 숫자가 아니라 문자열을 사용할 수도 있습니다. 즉, 인덱스는 first, second, third와 같은 문자열로 지정할 수도 있습니다. 반면에 행 번호는 데이터의 순서를 따라가기 때문에 정수만으로 데이터를 조회하거나 추출할 수 있으며 실제 데이터프레임에서는 확인할 수 없는 값입니다.

     

     

     

    loc 속성으로 행 데이터 추출하기

    1. loc 속성에 대괄호를 이용하여 인덱스를 전달하면 행 데이터를 추출할 수 있습니다. 다음은 인덱스가 0인 행 데이터를 추출한 것입니다. 만약 -1과 같이 인덱스에 없는 값을 사용하면 오류가 발생하니 주의하세요.

    print(df.loc[0]

    country      Afghanistan
    continent               Asia
    year                     1952
    lifeExp               28.801
    pop                8425333
    gdpPercap      779.445
    Name: 0, dtype: object

    print(df.loc[99])

    country      Bangladesh
    continent               Asia
    year                     1967
    lifeExp              43.453
    pop              62821884
    gdpPercap      721.186
    Name: 99, dtype: object


    print(df.loc[-1])

    -----------------------------------------------------------------------------------------
    KeyError                                        Traceback (most recent call last)
    ...
    KeyError: 'the label [-1] is not in the [index]'

     

    2. 만약 데이터프레임의 마지막 행 데이터를 추출하려면 어떻게 해야 할까요? 마지막 행 데이터의 인덱스를 알아내야 합니다. shape[0]에 행 크기(1704)가 저장되어 있다는 점을 이용하여 마지막 행의 인덱스를 구하면 됩니다. 다음은 shape[0]에서 1을 뺀 값으로(1704 - 1 = 1703) 마지막 행 데이터를 추출한 것입니다.

    number_of_rows = df.shape[0]
    last_row_index = nuber_of_rows - 1
    print(df.loc[las_row_index])

    country      Zimbabwe
    continent          Africa
    year                   2007
    lifeExp            43.487
    pop             12311143
    gdpPercap    469.709
    Name: 1703, dtype: object

     

    3. 데이터프레임의 마지막 행 데이터를 추출하는 또 다른 방법으로는 tail 메서드를 사용하는 방법이 있습니다. 다음과 같이 tail 메서드의 인자 n에 1을 전달하면 마지막 행의 데이터를 추출할 수 있습니다. 이 방법이 조금 더 유용하겠죠?

    print(df.tail(n=1))

                    country     continent    year    lifeExp            pop      gdpPercap
    1703   Zimbabwe           Africa   2007    43.487   12311143    469.709298

     

    4. 만약 인덱스가 0, 99, 999인 데이터를 한 번에 추출하려면 리스트에 원하는 인덱스를 담아 loc 속성에 전달하면 됩니다.

    print(df.loc[[0, 99, 999]])

                    country     continent    year    lifeExp            pop      gdpPercap
    0       Afghanistan             Asia   1952    28.801     8425333    779.445314
    99     Bangladesh             Asia   1967    43.453   62821884    721.186086
    999       Mongolia             Asia   1967     51.253     1149500  1226.041130

     

     

    ▶ tail 메서드와 loc 속성이 반환하는 자료형은 서로 달라요!

    tail 메서드와 loc 속성이 반환하는 데이터의 자료형은 다릅니다. 다음은 tail 메서드와 loc 속성으로 추출한 데이터의 자료형을 type 메서드로 확인한 것입니다. loc 속성이 반환한 데이터 자료형은 시리즈이고 tail 메서드가 반환한 데이터 자료형은 데이터프레임입니다.

    subset_loc = df.loc[0]
    subset_tail = df.tail(n=1)

    print(type(subset_loc))
    print(type(subset_tail))

    <class 'pandas.core.series.Series'>
    <class 'pandas.core.frame.DataFrame'>

     

     

     

    iloc 속성으로 행 데이터 추출하기

    1. 이번에는 iloc 속성으로 행 데이터를 추출하는 방법에 대해 알아보겠습니다. loc 속성은 데이터프레임의 인덱스를 사용하여 데이터를 추출했지만 iloc 속성은 데이터 순서를 의미하는 행 번호를 사용하여 데이터를 추출합니다. 지금은 인덱스와 행 번호가 동일하여 동일한 결괏값이 출력됩니다. 다음은 iloc 속성에 1을 전달하여 데이터를 추출한 것입니다.

    print(df.iloc[1])

    country        Afghanistan
    continent                 Aisa
    year                       1957
    lifeExp                30.332
    pop                  9240934
    gdpPercap        820.853
    Name: 1, dtype: object

    print(df.iloc[99])

    country       Bangladesh
    continet                  Aisa
    year                      1967
    lifeExp               43.453
    pop               62821884
    gdpPercap       721.186
    Name: 99, dtype: object

     

    2. iloc 속성은 음수를 사용해도 데이터를 추출할 수 있습니다. 다음은 -1을 전달하여 마지막 행 데이터를 추출한 것입니다. 하지만 데이터프레임에 아예 존재하지 않는 행 번호를 전달하면 오류가 발생합니다.

    print(df.iloc[-1])

    country      Zimbabwe
    continent          Africa
    year                   2007
    lifeExp            43.487
    pop             12311143
    gdpPercap    469.709
    Name: 1703, dtype: object

    print(df.iloc[1710])

    --------------------------------------------------------------------------------------
    IndexError                                  Traceback (most recent call last)
    <ipython-input-47-e91d411323c7> in <module>( )
    ----> 1 print(df.iloc[1710])
    ...
    IndexError: single positional indexer is out-of-bounds

     

    3. iloc 속성도 여러 데이터를 한 번에 추출할 수 있습니다. loc 속성을 사용했던 것처럼 원하는 데이터의 행 번호를 리스트에 담아 전달하면 됩니다.

    print(df.iloc[[0, 99, 999]])

                   country    continent     year      lifeExp            pop        gdpPercap
    0      Afghanistan            Asia    1952      28.801     8425333     779.445314
    99    Bangladesh            Asia    1967      43.453     2821884     721.186086
    999      Mongolia            Asia    1967      51.253      1149500   1226.041130

     

     

     

     

    loc, iloc 속성 자유자재로 사용하기

    loc, iloc 속성을 좀 더 자유자재로 사용하려면 추출할 데이터의 행과 열을 지정하는 방법을 알아야 합니다. 두 속성 모두 추출할 데이터의 행을 먼저 지정하고 그런 다음 열을 지정하는 방법으로 데이터를 추출합니다. 즉, df.loc[[행], [열]]이나 df.iloc[[행], [열]]과 같은 방법으로 코드를 작성하면 됩니다.

     

    이때 행과 열을 지정하는 방법은 슬라이싱 구문을 사용하는 방법과 range 메서드를 사용하는 방법이 있습니다. 먼저 슬라이싱 구문으로 원하는 데이터를 추출하는 방법을 알아보겠습니다.

     

     

     

    데이터 추출하기 - 슬라이싱 구문, range 메서드

    1. 슬라이싱 구문으로 데이터 추출하기

    다음은 모든 행(:)의 데이터에 대해 year, pop 열을 추출하는 방법입니다. 이때 loc와 iloc 속성에 전달하는 열 지정값은 반드시 형식에 맞게 전달해야 합니다. 예를 들어 loc 속성의 열 지정값에 정수 리스트를 전달하면 오류가 발생합니다.

    subset = df.loc[:, ['year', 'pop']]
    print(subset.head( ))

           year                pop
    0    1952        8425333
    1    1957        9240934
    2    1962      10267083
    3    1967      11537966
    4    1972      13079460

    subset = df.iloc[:, [2, 4, -1]]
    print(subset.head( ))

           year                pop     gdpPercap
    0    1952        8425333    779.445314
    1    1957        9240934    820.853030
    2    1962      10267083    853.100710
    3    1967      11537966    836.197138
    4    1972      13079460    739.981106

     

    2. range 메서드로 데이터 추출하기

    이번에는 iloc 속성과 파이썬 내장 메서드인 range를 응용하는 방법을 알아보겠습니다. range 메서드는 지정한 구간의 정수 리스트를 반환해 줍니다. iloc 속성의 열 지정값에는 정수 리스트를 전달해야 한다는 점과 range 메서드의 반환값이 정수 리스트인 점을 이용하여 원하는 데이터를 추출하는 것이죠.

    그런데 range 메서드는 조금 더 정확하게 말하면 지정한 범위의 정수 리스트를 반환하는 것이 아니라 제네레이터를 반환합니다. iloc 속성은 제네레이터로 데이터 추출을 할 수 없죠. 다행히 제네레이터는 간단하게 리스트로 변환할 수 있습니다. 다음은 range(5)가 반환한 제네레이터를 정숫값을 가진 리스트 [0, 1, 2, 3, 4]로 변환하여 iloc의 열 지정값에 전달한 것입니다. 자주 사용하는 방법은 아니지만 알아두면 유용할 것입니다.

    small_range = list(range(5))
    print(small_range)

    [0, 1, 2, 3, 4]

    print(type(small_range))

    <class 'list'>

    subset = df.iloc[:, small_range]
    print(subset.head( ))

               country  continent    year    lifeExp            pop   
    0  Afghanistan          Asia   1952    28.801     8425333   
    1  Afghanistan          Asia   1957    30.332     9240934  
    2  Afghanistan          Asia   1965    31.997   10267083  
    3  Afghanistan          Asia   1967    34.020   11537966 
    4  Afghanistan          Asia   1972    36.088   13079460 


    small_range = list(range(3, 6))
    print(small_range)

    [3, 4, 5]

    subset = df.iloc[:, small_range]
    print(subset.head( ))

          lifeExp             pop     gdpPercap
    0    28.801     8425333    779.445314
    1    30.332     9240934    820.853030
    2    31.997   10267083    853.100710
    3    34.020   11537966    836.197138
    4    36.088   13079460    739.981106

     

    3. range 메서드에 대해 조금 더 알아볼까요? range 메서드에 range(0, 6, 2)와 같은 방법으로 3개의 인자를 전달하면 어떻게 될까요? 0부터 5까지 2만큼 건너뛰는 제네레이터를 생성합니다. 이 제네레이터를 리스트로 변환하는 범위는 0~5이고 짝수로 된 정수 리스트를 얻을 수 있죠.

    small_range = list(range(0, 6, 2))
    subset = df.iloc[:, small_range]
    print(subset.head( ))

                 country    year                pop
    0    Afghanistan   1952        8425333
    1    Afghanistan   1957        9240934
    2    Afghanistan   1962      10267083
    3    Afghanistan   1967      11537966
    4    Afghanistan   1972      13079460

     

    4.슬라이싱 구문과 range 메서드 비교하기

    그런데 실무에서는 range 메서드보다는 간편하게 사용할 수 있는 파이썬 슬라이싱 구문을 더 선호합니다. range 메서드가 반환한 제네레이터를 리스트로 변환하는 등의 과정을 거치지 않아도 되기 때문이죠. 예를 들어 list(range(3))과 [:3]의 결괏값은 동일합니다.

    subset = df.iloc[:, :3]
    print(subset.head( ))

                 country    continent    year   
    0    Afghanistan            Asia   1952 
    1    Afghanistan            Asia   1957       
    2    Afghanistan            Asia   1962    
    3    Afghanistan            Asia   1967   
    4    Afghanistan            Asia   1972  

     

    5. 0:6:2를 열 지정값에 전달하면 과정 3에서 얻은 결괏값과 동일한 결괏값을 얻을 수 있습니다. range 메서드와 슬라이싱 구문을 비교해 보세요.

    subset = df.iloc[:, 0:6:2]
    print(subset.head( ))

                 country    year                pop
    0    Afghanistan   1952        8425333
    1    Afghanistan   1957        9240934
    2    Afghanistan   1962      10267083
    3    Afghanistan   1967      11537966
    4    Afghanistan   1972      13079460

     

    6.loc, iloc 속성 자유자재로 사용하기

    만약 iloc 속성으로 0, 99, 999번째 행의 0, 3, 5번째 열 데이터를 추출하려면 다음과 같이 코드를 작성하면 됩니다.

    print(df.iloc[[0, 99, 999], [0, 3, 5]])

                   country    lifeExp      gdpPercap
    0      Afghanistan    28.801     779.445314
    99    Bangladesh    43.453     721.186086
    999      Mongolia    51.253    1226.041130

     

    7. iloc 속성의 열 지정값으로 정수 리스트를 전달하는 것이 간편해 보일 수 있지만 이렇게 작성한 코드는 나중에 어떤 데이터를 추출하기 위한 코드인지 파악하지 못 할 수도 있습니다. 그래서 보통은 다음과 같은 방법으로 loc 속성을 이용하여 열 지정값으로 열 이름을 전달합니다.

    print(df.loc[[0, 99, 999], ['country', 'lifeExp', 'gdpPercap']])

                   country    lifeExp      gdpPercap
    0      Afghanistan    28.801     779.445314
    99    Bangladesh    43.453     721.186086
    999      Mongolia    51.253    1226.041130

     

    8. 앞에서 배운 내용을 모두 응용하여 데이터를 추출해 볼까요? 다음은 인덱스가 10인 행부터 13인 행의 country, lifeExp, gdpPercap 열 데이터를 추출하는 코드입니다.

    print(df.loc[10:13, ['country', 'lifeExp', 'gdpPercap']])

                 country    lifeExp      gdpPercap
    10  Afghanistan    42.129    726.734055
    11  Afghanistan    43.828    974.580338
    12         Albania    55.230  1601.056136
    13         Albania    59.280  1942.284244

     

     

     

     

     

     

    출처 : "판다스 입문"

Designed by Tistory.