-
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: object2. 리스트에 열 이름을 전달하면 여러 개의 열을 한 번에 추출할 수 있습니다. 다음은 열 이름이 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: object3. 데이터프레임의 마지막 행 데이터를 추출하는 또 다른 방법으로는 tail 메서드를 사용하는 방법이 있습니다. 다음과 같이 tail 메서드의 인자 n에 1을 전달하면 마지막 행의 데이터를 추출할 수 있습니다. 이 방법이 조금 더 유용하겠죠?
print(df.tail(n=1))
country continent year lifeExp pop gdpPercap
1703 Zimbabwe Africa 2007 43.487 12311143 469.7092984. 만약 인덱스가 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: object2. 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-bounds3. 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.041130loc, 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.9811062. 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.9811063. 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 130794604.슬라이싱 구문과 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 19725. 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 130794606.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.0411307. 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.0411308. 앞에서 배운 내용을 모두 응용하여 데이터를 추출해 볼까요? 다음은 인덱스가 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출처 : "판다스 입문"
'Do it! 판다스 입문' 카테고리의 다른 글
Chapter 04-1 데이터 시각화가 필요한 이유 (0) 2022.06.20 Chapter 03-4~03-6 데이터프레임 다루기, 시리즈와 데이터프레임의 데이터 처리하기, 데이터 저장하고 불러오기 (0) 2022.06.13 Chapter 03-1~03-3 나만의 데이터 만들기, 시리즈 다루기(기초,응용) (0) 2022.06.13 Chapter.02-3~02-4 기초적인 통계 계산하기, 그래프 그리기 (0) 2022.06.12 Chapter 02-1 데이터 집합 불러오기 (0) 2022.06.11