판다스에서 데이터프레임과 시리즈는 판다스를 효율적으로 사용하게 해주는 자료형이다.
데이터프레임(DataFrame)은 엑셀에서의 시트와 동일한 개념이며 시리즈(Series)는 시트의 열 1개를 의미한다.
데이터를 가져와 살펴보자.
import pandas as pd
df = pd.read_csv('../data/gapminder.tsv', sep='\t')
print(df.head(), '\n')
print(type(df), '\n')
print(df.shape, '\n')
print(df.columns, '\n') # 판다스에서는 object가 string!
print(df.info())
pandas의 read_csv메서드는 데이터 집합을 읽어들어와 데이터프레임으로 전환해준다.
gapminder라는 파일을 가져와보았다.
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 1962 31.997 10267083 853.100710
3 Afghanistan Asia 1967 34.020 11537966 836.197138
4 Afghanistan Asia 1972 36.088 13079460 739.981106
<class 'pandas.core.frame.DataFrame'>
(1704, 6)
Index(['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap'], dtype='object')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1704 entries, 0 to 1703
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 country 1704 non-null object
1 continent 1704 non-null object
2 year 1704 non-null int64
3 lifeExp 1704 non-null float64
4 pop 1704 non-null int64
5 gdpPercap 1704 non-null float64
dtypes: float64(2), int64(2), object(2)
memory usage: 80.0+ KB
None
1704개의 행과 6개의 열로 이루어진 데이터임을 확인하였다.
type메서드를 통해 읽어온 데이터가 데이터프레임이라는 것을 알 수 있다.
판다스에서는 string을 object로 표기한다는 특징이 있다.
head메서드는 실제 데이터프레임의 일부를 보여준다. n이라는 인자에 숫자를 넣어 보고 싶은 데이터 행의 개수를 정할 수 있다.
info는 각 열이 어떤 정보를 어떤 자료형으로 담고 있으며 그 수가 몇 개 인지에 대한 정보를 준다.
print(df.loc[0]) # loc는 행의 index number로 추출
country Afghanistan
continent Asia
year 1952
lifeExp 28.801
pop 8425333
gdpPercap 779.445314
Name: 0, dtype: object
loc라는 내부함수를 이용하여 각 행의 데이터에 접근할 수 있다.
loc는 행의 index number를 인자로 넣어준다.
print(df.iloc[0]) # iloc는 행 number로 추출
print(df.iloc[-1]) # iloc는 loc와 달리 음수도 가능!
country Afghanistan
continent Asia
year 1952
lifeExp 28.801
pop 8425333
gdpPercap 779.445314
Name: 0, dtype: object
country Zimbabwe
continent Africa
year 2007
lifeExp 43.487
pop 12311143
gdpPercap 469.709298
Name: 1703, dtype: object
iloc는 행에 지정된 number로 각 행의 데이터에 접근한다.
가져온 데이터프레임은 index number와 마찬가지로 0부터 시작하기 때문에 여기서는 iloc와 loc의 결과가 같다.
iloc는 loc와는 다르게 음수를 사용하여 값을 출력할 수 있다.
print(df.tail(n=3))
print(type(df.loc[0]), type(df.tail(n=1))) # loc와 tail의 type이 다르다!
country continent year lifeExp pop gdpPercap
1701 Zimbabwe Africa 1997 46.809 11404948 792.449960
1702 Zimbabwe Africa 2002 39.989 11926563 672.038623
1703 Zimbabwe Africa 2007 43.487 12311143 469.709298
<class 'pandas.core.series.Series'> <class 'pandas.core.frame.DataFrame'>
tail은 마지막 행데이터부터 n인자에 지정한 수만큼의 데이터에 접근한다.
특이한 점은 tail메서드를 통해 접근한 데이터의 타입은 데이터프레임이지만 loc의 경우에는 시리즈이다.
subset = df.loc[:, ['year', 'pop']] # loc는 열의 문자열 이름을 넣어서 추출
print(subset.head())
subset = df.iloc[:, [2, 4, -1]] # iloc는 열의 인덱스 번호를 넣어서 추출
print(subset.head())
year pop
0 1952 8425333
1 1957 9240934
2 1962 10267083
3 1967 11537966
4 1972 13079460
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
loc와 iloc 메서드를 사용하여 열 데이터에도 접근이 가능하다.
loc는 열의 이름을 통해 접근하고 iloc는 열의 인덱스를 통해 접근한다.
아무래도 iloc를 사용하면 따로 출력해보지 않는 이상 어떤 데이터인지 불분명하므로 loc를 통해 열 이름으로 접근하는 것이 더 좋다.
print(df.loc[10:13, ['country', 'lifeExp', 'gdpPercap']])
country year
0 Afghanistan 1952
1 Afghanistan 1957
2 Afghanistan 1962
3 Afghanistan 1967
4 Afghanistan 1972
위와 같이 슬라이싱을 하는 것도 가능하다.
groupby 메서드를 이용하여 연도별('year')로 정보에 접근이 가능하다.
groupby 메서드는 여러 개의 항목을 세분화해서 그룹화할 수 있다는 점에서 강점을 지닌다.
print(df.groupby('year')['lifeExp'].mean())
# 연도별로(각 국가마다 같은 연도의 데이터가 존재하므로) 모든 국가의 lifeExp의 평균을 구한 값
year
1952 49.057620
1957 51.507401
1962 53.609249
1967 55.678290
1972 57.647386
1977 59.570157
1982 61.533197
1987 63.212613
1992 64.160338
1997 65.014676
2002 65.694923
2007 67.007423
Name: lifeExp, dtype: float64
내가 접근한 방식에 따라서 groupby만 적용한 데이터는 데이터프레임, 추가로 lifeExp 열에 접근한 데이터는 시리즈의 형태이며 서로 다른 메모리 주소에 저장되어 있는 것을 알 수 있다.
groupby를 통해 얻은 데이터는 아래와 같은 타입(SeriesGroupBy)을 가진다는 것을 알 수 있다.
print(df.groupby('year'))
print(df.groupby('year')['lifeExp'])
# groupby를 통해 나온 데이터는 데이터프레임의 형태로 저장되어 다음의(0x7fc57cded400) 메모리주소에 저장되었다는 것을 확인할 수 있음.
print(type((df.groupby('year')['lifeExp'])))
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fc57cded490>
<pandas.core.groupby.generic.SeriesGroupBy object at 0x7fc57cded130>
<class 'pandas.core.groupby.generic.SeriesGroupBy'>
데이터의 개수를 구하고 싶을 때는 nunique라는 메서드를 사용하면 된다. 매우 유용하다!
print(df.groupby('continent')['country'].nunique()) # 각 항목에 해당하는 데이터의 개수를 출력
# 여기서는 각 대륙별 몇 개의 나라가 포함되어 있는지 개수를 구하는 코드!
continent
Africa 52
Americas 25
Asia 33
Europe 30
Oceania 2
Name: country, dtype: int64
데이터의 추이를 보고 싶을 때 그래프만한 것이 없다.
matplotlib를 가져와 간단한 그래프를 그려보자.
import matplotlib.pyplot as plt
global_yearly_mean_life_expectancy = df.groupby('year')['lifeExp'].mean()
print(global_yearly_mean_life_expectancy)
year
1952 49.057620
1957 51.507401
1962 53.609249
1967 55.678290
1972 57.647386
1977 59.570157
1982 61.533197
1987 63.212613
1992 64.160338
1997 65.014676
2002 65.694923
2007 67.007423
Name: lifeExp, dtype: float64
임의로 연도별 국가들의 gdp의 평균 데이터를 가져왔다.
이제 이 데이터로 쉽게 그래프를 그릴 수 있다.
global_yearly_mean_life_expectancy.plot()
<AxesSubplot:xlabel='year'>

그래프를 통해 국가들의 평균 gdp가 꾸준히 상승하는 것을 한 눈에 볼 수 있다.
'Pandas' 카테고리의 다른 글
[Do it! Pandas] 7. 깔끔한 데이터 (0) | 2023.02.12 |
---|---|
[Do it! Pandas] 6. 누락값 처리하기 (0) | 2023.02.12 |
[Do it! Pandas] 5. 데이터 연결하기 (0) | 2023.02.12 |
[Do it! Pandas] 4. matplotlib 라이브러리를 이용한 다양한 그래프 그리기 (0) | 2023.02.10 |
[Do it! Pandas] 데이터프레임과 시리즈, 브로드캐스팅 (0) | 2023.02.09 |