판다스 자료 구조 소개
import pandas as pd
import numpy as np
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
판다스 자료 구조 소개¶
Series¶
Series
- 일련의 객체를 담을 수 있는 1차원 배열 같은 자료구조이다
- 색인(index)라 하는 배열의 데이터와 연관된 이름을 갖는다
- 왼쪽은 색인, 오른쪽은 해당 색인의 값
from pandas import Series, DataFrame
s1 = pd.Series([4, 7, -5, 3])
s1
0 4
1 7
2 -5
3 3
dtype: int64
s1.array
<PandasArray>
[4, 7, -5, 3]
Length: 4, dtype: int64
s1.index
RangeIndex(start=0, stop=4, step=1)
색인을 지정하여 넣을 수 있다
s2 = pd.Series([4, 7, -5, 3], index = ['d', 'b', 'a', 'c'])
s2
s2.index
d 4
b 7
a -5
c 3
dtype: int64
Index(['d', 'b', 'a', 'c'], dtype='object')
색인으로 레이블(label)을 사용할 수 있다
s2['a']
s2['d'] = 6
s2
-5
d 6
b 7
a -5
c 3
dtype: int64
블리언 배열을 사용해 값을 걸러내거나, 스칼라 곱셈, 수학 함수를 적용하는 등 넘파이 배열 연산을 수행해도 색인과 값 연결을 유지
# 블리언
s2[s2 > 0]
d 6
b 7
c 3
dtype: int64
# 스칼라 곱셉
s2 * 2
d 12
b 14
a -10
c 6
dtype: int64
# 수학 함수
np.exp(s2)
d 403.428793
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
파이썬의 딕셔너리와 비슷하다 -> 파이썬의 딕셔러니가 필요한 곳에 Series 객체를 사용
'b' in s2
True
'e' in s2
False
sdata ={'ohio' : 35000, 'texas' : 7100, 'oregon' : 16000, 'utah' : 5000}
s3 = pd.Series(sdata)
s3
ohio 35000
texas 7100
oregon 16000
utah 5000
dtype: int64
to_dict메서드를 사용해 Series를 다시 딕셔너리로 표현
s3.to_dict()
{'ohio': 35000, 'texas': 7100, 'oregon': 16000, 'utah': 5000}
california에 대한 값은 없으므로 NaN이 표시 -> 누락 값을 NA, null이라 한
states = ['california', 'ohio', 'oregon' ,'texas']
s4 = pd.Series(sdata, index = states)
s4
california NaN
ohio 35000.0
oregon 16000.0
texas 7100.0
dtype: float64
.isnull(), .notnull()는 누락된 데이터를 찾을 때 이용
s4.isna()
california True
ohio False
oregon False
texas False
dtype: bool
s4.notna()
california False
ohio True
oregon True
texas True
dtype: bool
산술 연산에서 색인과 레이블로 자동 정렬 가능 -> join 연산과 비슷
s3
s4
s3 + s4
ohio 35000
texas 7100
oregon 16000
utah 5000
dtype: int64
california NaN
ohio 35000.0
oregon 16000.0
texas 7100.0
dtype: float64
california NaN
ohio 70000.0
oregon 32000.0
texas 14200.0
utah NaN
dtype: float64
Series 객체와 색인은 모두 name 속성을 가지며 이 속성은 판다스의 다른 기능들과 통합
s4.name = 'population'
s4.index.name = 'state'
s4
state
california NaN
ohio 35000.0
oregon 16000.0
texas 7100.0
Name: population, dtype: float64
DataFrame¶
DataFrame
- 표 같은 스프레드시트 형식
- 행과 열에 대한 색인을 있다
- 색인의 모양이 같은 Series객체를 담고 있는 파이썬 딕셔너리로 생각
data = {'state' : ['ohio', 'ohio', 'ohio', 'nevada', 'nevada', 'nevada'],
'year' : [2000, 2001, 2002, 2001, 2002, 2003],
'pop' : [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
frame
state | year | pop | |
---|---|---|---|
0 | ohio | 2000 | 1.5 |
1 | ohio | 2001 | 1.7 |
2 | ohio | 2002 | 3.6 |
3 | nevada | 2001 | 2.4 |
4 | nevada | 2002 | 2.9 |
5 | nevada | 2003 | 3.2 |
frame.head()
frame.tail()
state | year | pop | |
---|---|---|---|
0 | ohio | 2000 | 1.5 |
1 | ohio | 2001 | 1.7 |
2 | ohio | 2002 | 3.6 |
3 | nevada | 2001 | 2.4 |
4 | nevada | 2002 | 2.9 |
state | year | pop | |
---|---|---|---|
1 | ohio | 2001 | 1.7 |
2 | ohio | 2002 | 3.6 |
3 | nevada | 2001 | 2.4 |
4 | nevada | 2002 | 2.9 |
5 | nevada | 2003 | 3.2 |
columns을 원하는 순서대로 지정하면 해당 순서로 정렬된 DataFrame 객체가 생성
pd.DataFrame(data, columns = ['year', 'state', 'pop'])
year | state | pop | |
---|---|---|---|
0 | 2000 | ohio | 1.5 |
1 | 2001 | ohio | 1.7 |
2 | 2002 | ohio | 3.6 |
3 | 2001 | nevada | 2.4 |
4 | 2002 | nevada | 2.9 |
5 | 2003 | nevada | 3.2 |
딕셔너리에 없는 값을 columns애 넘기면 결과에 결측치가 표시
frame2 = pd.DataFrame(data, columns = ['year', 'state', 'pop', 'debt'])
frame2
year | state | pop | debt | |
---|---|---|---|---|
0 | 2000 | ohio | 1.5 | NaN |
1 | 2001 | ohio | 1.7 | NaN |
2 | 2002 | ohio | 3.6 | NaN |
3 | 2001 | nevada | 2.4 | NaN |
4 | 2002 | nevada | 2.9 | NaN |
5 | 2003 | nevada | 3.2 | NaN |
DataFrame의 열은 Series처럼 딕셔너리 형식의 표기법이나 점 표기법으로 접근
frame['state']
0 ohio
1 ohio
2 ohio
3 nevada
4 nevada
5 nevada
Name: state, dtype: object
frame2.year # 파이썬에서 사용 가능한 변수 이름이며, 이름에 기호가 없을 때 사용O
0 2000
1 2001
2 2002
3 2001
4 2002
5 2003
Name: year, dtype: int64
frame2.loc[1]
frame2.iloc[2]
year 2001
state ohio
pop 1.7
debt NaN
Name: 1, dtype: object
year 2002
state ohio
pop 3.6
debt NaN
Name: 2, dtype: object
대입으로 열 수정
frame2['debt'] = 16.5
frame2
year | state | pop | debt | |
---|---|---|---|---|
0 | 2000 | ohio | 1.5 | 16.5 |
1 | 2001 | ohio | 1.7 | 16.5 |
2 | 2002 | ohio | 3.6 | 16.5 |
3 | 2001 | nevada | 2.4 | 16.5 |
4 | 2002 | nevada | 2.9 | 16.5 |
5 | 2003 | nevada | 3.2 | 16.5 |
frame2['debt'] = np.arange(6.)
frame2
year | state | pop | debt | |
---|---|---|---|---|
0 | 2000 | ohio | 1.5 | 0.0 |
1 | 2001 | ohio | 1.7 | 1.0 |
2 | 2002 | ohio | 3.6 | 2.0 |
3 | 2001 | nevada | 2.4 | 3.0 |
4 | 2002 | nevada | 2.9 | 4.0 |
5 | 2003 | nevada | 3.2 | 5.0 |
리스트나 배열을 열에 대입할 때는 대입하려는 값의 길이가 DataFrame의 길이와 동일
Series를 대입하면 DataFrame의 색인에 따라 값이 대입되며 존재하지 않는 색인에는 결측치가 대체
val = pd.Series([-1.2, -1.5, -1.7], index = ['two', 'four', 'five'])
frame2['debt'] = val
val
frame2
two -1.2
four -1.5
five -1.7
dtype: float64
year | state | pop | debt | |
---|---|---|---|---|
0 | 2000 | ohio | 1.5 | NaN |
1 | 2001 | ohio | 1.7 | NaN |
2 | 2002 | ohio | 3.6 | NaN |
3 | 2001 | nevada | 2.4 | NaN |
4 | 2002 | nevada | 2.9 | NaN |
5 | 2003 | nevada | 3.2 | NaN |
존재하지 않는 열을 대입할 경우에는 새로운 열이 생성
frame2['eastern'] = frame2['state'] == 'ohio'
frame2
year | state | pop | debt | eastern | |
---|---|---|---|---|---|
0 | 2000 | ohio | 1.5 | NaN | True |
1 | 2001 | ohio | 1.7 | NaN | True |
2 | 2002 | ohio | 3.6 | NaN | True |
3 | 2001 | nevada | 2.4 | NaN | False |
4 | 2002 | nevada | 2.9 | NaN | False |
5 | 2003 | nevada | 3.2 | NaN | False |
del을 사용해 열 삭제
del frame2['eastern']
frame2
year | state | pop | debt | |
---|---|---|---|---|
0 | 2000 | ohio | 1.5 | NaN |
1 | 2001 | ohio | 1.7 | NaN |
2 | 2002 | ohio | 3.6 | NaN |
3 | 2001 | nevada | 2.4 | NaN |
4 | 2002 | nevada | 2.9 | NaN |
5 | 2003 | nevada | 3.2 | NaN |
중첩된 딕셔너리로 데이터 생성
populations = {'ohio' : {2000:1.5, 2001:1.7, 2002:3.6},
'nevada' : {2001:2.4, 2002:2.9}}
frame3 = pd.DataFrame(populations)
frame3
ohio | nevada | |
---|---|---|
2000 | 1.5 | NaN |
2001 | 1.7 | 2.4 |
2002 | 3.6 | 2.9 |
행과 열을 뒤집기
frame3.T
2000 | 2001 | 2002 | |
---|---|---|---|
ohio | 1.5 | 1.7 | 3.6 |
nevada | NaN | 2.4 | 2.9 |
Series 객체를 담고 있는 딕셔너리 데이터도 동일한 방식으로 취급
pdata = {'ohio' : frame3['ohio'][:-1],
'nevada' : frame3['nevada'][:2]}
pd.DataFrame(pdata)
ohio | nevada | |
---|---|---|
2000 | 1.5 | NaN |
2001 | 1.7 | 2.4 |
index, column에 이름 지정
frame3.index.name = 'year'
frame3.columns.name = 'state'
frame3
state | ohio | nevada |
---|---|---|
year | ||
2000 | 1.5 | NaN |
2001 | 1.7 | 2.4 |
2002 | 3.6 | 2.9 |
DataFrame에 포함된 데이터를 2차원 형태의 ndarray로 반환
frame3.to_numpy()
array([[1.5, nan],
[1.7, 2.4],
[3.6, 2.9]])
frame2.to_numpy()
array([[2000, 'ohio', 1.5, nan],
[2001, 'ohio', 1.7, nan],
[2002, 'ohio', 3.6, nan],
[2001, 'nevada', 2.4, nan],
[2002, 'nevada', 2.9, nan],
[2003, 'nevada', 3.2, nan]], dtype=object)
색인 객체¶
색인 객체
- Series나 DataFrame 객체를 생성할 때 사용하는 배열이나 다른 순차적인 레이블은 내부적으로 색인으로 변환
s1 = pd.Series(np.arange(3), index = ['a', 'b', 'c'])
index = s1.index
index
index[1:]
Index(['a', 'b', 'c'], dtype='object')
Index(['b', 'c'], dtype='object')
labels = pd.Index(np.arange(3))
labels
s2 = pd.Series([1.5, -2.5, 0], index = labels)
s2
Index([0, 1, 2], dtype='int64')
0 1.5
1 -2.5
2 0.0
dtype: float64