[Pandas] 소개 / 시리즈와 데이터프레임
소개
Pandas는 파이썬 프로그래밍 언어를 위해 "높은 성능"과 "쉬운 사용"으로 데이터 구조와 분석 툴을 제공하는 오픈소스 BSD 라이선스 라이브러리이다.
pandas 공식 문서의 첫 줄의 내용만으로 우리가 Pandas를 공부해야 하는 이유가 명확해졌다.
공식 문서는 제품을 구매하면 함께 오는 사용 설명서라고 생각하면 되는데, 구글링을 통해서도 나오지 않는 내용은
공식 문서 Documentation을 통해 찾아 보는것도 하나의 방법이 될 수 있겠다.
import pandas as pd
먼저 numpy에서 그랬듯 pandas를 불러 오는 방법도 동일하다. import pandas as pd를 통해 pandas 사용을 선언하고
as pd를 통해 pandas 명령어를 pd로 축약하여 사용하자
pandas 소개 글을 살펴본 바로 pandas는 데이터를 데이터를 다루는 툴이기 때문에 이를 편리하게 사용하기 위해
쓰이는 문구 역시 존재한다.
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_nodeinteractivity = "all"
위 코드를 실행하게되면 print( )를 사용하지 않고 2개 이상의 표를 깔끔하게 출력할 수 있다.
다시 정리 하자면 pandas를 사용하기 위해선 총 3개의 코드를 기본적으로 깔고 시작해야 한다.
import pandas as pd
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_nodeinteractivity = "all"
Pandas는 Series, dataFrame이라고 부르는 두 가지 형태의 자료 구조를 갖는데 Series는 1차원 데이터라고도 부르고
DataFrame은 2차원 데이터라고 부르며, 표 형태의 자료 구조를 떠올리면 이해가 쉽다.
DataFrame을 구성은 여러 개의 Series이기 때문에 하나의 열(column), 행(row)은 하나의 Series이다.
Series는 1차원 데이터라고 했지만, 그림에서는 index와 data 두 가지의 자료를 가지고 있다.
이는 Series 데이터가 value와 index로 구성되어있다는 것을 뜻 하고, 'Series 데이터가 한 줄이다.'라는 말은
value가 한 줄이라는 의미이다.
s = pd.Series([1,3,5,6,8])
print(s)
0 1
1 3
2 5
3 6
4 8
dtype: int64
Series에서 index 값을 따로 지정하지 않으면 요소의 개 수에 맞춰 자동으로 출력된다.
예시 코드 역시, value 값만 지정해서 출력했는데, 출력 결과 0,1,2,3,4라는 index가 함께 출력되었다.
# index 지정하여 출력하기
s = pd.Series([1,3,5,6,8], index=['하나','둘','셋','넷','다섯'])
print(s)
하나 1
둘 3
셋 5
넷 6
다섯 8
dtype: int64
list, tuple, dictionary 바꾸기
list, tuple
먼저 list와 tuple을 Series로 바꾸는 방법은 동일하다.
변수에 담긴 value list와 index list를 pd.Series(변수 1, 인덱스 1) 형식으로 넣어 사용하고
마찬가지로 변수에 담긴 value tuple, index tuple을 pd.Series(변수 1, 인덱스 1) 형태로 넣는다.
a = [1,3,5,6,8]
list_index = ['하나','둘','셋','넷','다섯']
series = pd.Series(a, index=list_index)
print(s)
하나 1
둘 3
셋 5
넷 6
다섯 8
dtype: int64
[79]
12345678
tuple_data = (1,3,5,6,8)
series = pd.Series(tuple_data)
print(series)
print()
tuple_index = ('하나','둘','셋','넷','다섯')
series_1 = pd.Series(tuple_data, index=tuple_index)
print(series_1)
0 1
1 3
2 5
3 6
4 8
dtype: int64
하나 1
둘 3
셋 5
넷 6
다섯 8
dtype: int64
dictionary
dictionary가 key와 value로 구성된 데이터 임을 잘 파악하고 있다면,
Series 데이터의 index와 value라는 요소를 보고 자연스레 dictionary를 떠올렸을 것이다.
Dict | Series |
key | index |
value | value |
다시 말해 위의 표와 같이 매칭이 가능하다.
dict_data = {'a':1,'b':2,'c':3}
sr = pd.Series(dict_data)
print(dict_data)
print()
print(type(sr))
print()
print(sr)
{'a': 1, 'b': 2, 'c': 3}
<class 'pandas.core.series.Series'>
a 1
b 2
c 3
dtype: int64
dict를 Series로 변환시킬 때에는 별도로 index를 지정하지 않아도 key 값이 index로 넘어가 변환된다.
원소 선택
list, tuple, dict를 series로 변환시키고, 만드는 걸 알아봤다면 이번엔 만든 Series의 특정 원소를 가져와보자
Series의 원소를 선택할 때는 index 이름, 위치를 이용해 원소를 가져올 수 있다.
원소 선택 방식
- 하나만 선택
- 여러 개 선택
- 슬라이싱으로 선택
처음 Series를 이해하기 위해 사용했던 그림을 다시 살펴보면,
index를 특정하지 않았을 경우 자동으로 순서가 정해져 출력이 된다고 했는데
이런 index를 정수형 index라고 한다.
만약 사용자가 index의 이름을 특정하였더라도 정수형 index는 사라지지 않고
남아있기 때문에 언제든 이를 이용해 사용할 수 있다.
- 정수형 위치 index : 언제나 사용 가능
- index 특정 이름 : 지정한 이름으로 사용 가능
단일 원소 가져오기
123456789101112
s_data = pd.Series(['바나나','원래','하얗다','색소','무첨가'],
index = ['Bananas','are originally', 'white','No added','color'])
# 정수형 위치 index 가져오기
num_index = s_data[2]
print(num_index)
# index 이름으로 가져오기
name_index = s_data['are originally']
print(name_index)
print()
print(s_data)
하얗다
원래
+++++++++++++++++++++++++++++++++++++++++++++
Bananas 바나나
are originally 원래
white 하얗다
No added 색소
color 무첨가
dtype: object
리스트의 원소 가져오기를 통해 list [num] 형태로 원소를 가져오는 건 익숙할 테지만,
index 이름을 통해 원소를 가져오는 건 조금 생소해 적응하는데 조금 시간이 걸렸다.
여러 원소 가져오기
s_data = pd.Series(['바나나','원래','하얗다','색소','무첨가'],
index = ['Bananas','are originally', 'white','No added','color'])
# 정수형 위치로 여러 원소 가져오기
num_index = s_data[[0,3,4]]
print(num_index)
print()
# index 이름으로 여러 원소 가져오기
name_index = s_data[['No added','are originally']]
print(name_index)
Bananas 바나나
No added 색소
color 무첨가
dtype: object
++++++++++++++++++++++++++++++++++++++++
No added 색소
are originally 원래
dtype: object
단일 원소 가져오는 방법과 동일하지만 대괄호 [ ]를 한 번 더 감싸줘야 호출할 수 있다.
슬라이싱으로 원소 선택
s_data = pd.Series(['바나나','원래','하얗다','색소','무첨가'],
index = ['Bananas','are originally', 'white','No added','color'])
# 정수형 위치 슬라이싱으로 여러 원소 가져오기
num_index = s_data[1:4]
print(num_index)
print()
# index 이름 슬라이싱으로 여러 원소 가져오기
name_index = s_data['Bananas':'color']
print(name_index)
are originally 원래
white 하얗다
No added 색소
dtype: object
++++++++++++++++++++++++++++++++++++++++++++
Bananas 바나나
are originally 원래
white 하얗다
No added 색소
color 무첨가
dtype: object
슬라이싱 역시 정수, index 모두 가능한데, 짚고 넘어가야 할 점이 있다.
정수형은 기존 ~ 이상 ~ 미만이 적용되어있지만 index 이름형은 ~ 이상 ~이하가 적용되어
0부터 5까지의 인덱스가 모두 출력되었다. 이건 index 이름 형만이 가지는 고유한 특성이니 알아가자
value, index 값 한 번에 불러오기
import pandas as pd
series = pd.Series(['wlcome','to','pandas','world'],
index = [1,2,3,4])
print(series.index)
print()
print(series.values)
Int64Index([1, 2, 3, 4], dtype='int64')
['wlcome' 'to' 'pandas' 'world']
x.index , x.values를 통해 Series에 들어간 모든 데이터를 한 번에 받을 수 있다.
DataFrame( )
DataFrame은 '표' 형태로 이루어진 2차원 데이터를 말한다. rows(행)과 columns(열)로 이루어져 있으며,
열한 줄 한 줄은 모두 Series로 구성되어있다. Series로 구성되어있기 때문에 정수형 위치 인덱스가 존재한다.
기본 형태
DataFrame(2차원 리스트 or튜플 or딕셔너리,
index = ,
column )
# list dataframe
list_data = [[23,'남','부산'],[21,'여','서울'],[25,'남','광주'],
[27,'여','대전'],[24,'여','광주']]
df = pd.DataFrame(list_data,
index = ['민지','성우','지현','정민','수민'],
columns = ['나이','성별','지역'])
print(df)
나이 성별 지역
민지 23 남 부산
성우 21 여 서울
지현 25 남 광주
정민 27 여 대전
수민 24 여 광주
#tuple dataframe
tuple_data = ((23,'남','부산'),(21,'여','서울'),(25,'남','광주'),
(27,'여','대전'),(24,'여','광주'))
df = pd.DataFrame(list_data,
index = ['민지','성우','지현','정민','수민'],
columns = ['나이','성별','지역'])
print(df)
나이 성별 지역
민지 23 남 부산
성우 21 여 서울
지현 25 남 광주
정민 27 여 대전
수민 24 여 광주
#dictionary dataframe
dict_data = {'나이' : [23,21,25,27,24], '성별' : ['남','여','남','여','여'],'지역' : ['부산','서울','광주','대전','광주']}
df = pd.DataFrame(list_data,
index = ['민지','성우','지현','정민','수민'],
columns = ['나이','성별','지역'])
print(df)
나이 성별 지역
민지 23 남 부산
성우 21 여 서울
지현 25 남 광주
정민 27 여 대전
수민 24 여 광주
각각의 타입에 맞게 대중소 괄호를 적용하여 만들어 주면 되는데, 튜플은 내부 내용 역시 소괄호로 묶어줘야 한다.
특정 데이터 선택하기
열 선택
- DataFrame[['열 이름', '열 이름', '열 이름']]
- DataFrame. '열 이름'
test_data = {'이름' : [1,2,3,4,5],
'창의' : [4,4,1,3,5],
'완성' : [4,1,2,1,3],
'사업' : [5,4,1,1,3]}
df = pd.DataFrame(test_data)
print(df[['이름','완성']])
이름 완성
0 1 4
1 2 1
2 3 2
3 4 1
4 5 3
원하는 열 데이터를 출력하고자 할 때에는 두 가지 형태로 출력할 수 있는데,
대괄호 [ ]로 감싸 문자열 형태로 불러오는 방법이다, 이 방법을 사용할 경우 하나의 단일 데이터가 아닌,
여러 개의 데이터를 함께 불러올 수 있다.
다음은 객체 뒤에 콤마. 를 찍고 불러오는 방법인데, 단일 데이터만 불러올 수 있다는 차이를 인지 하길 바란다.
행 선택
열을 선택할 때 대괄호 [ ] 문자열과 콤마 . 문자열 형식으로 불러왔다면,
행을 선택 할 때에는 loc, iloc 두 가지를 사용해 불러올 수 있다. 먼저 loc는 label을 이용하여 값을 선택하는 건데
label이란 정수형 위치 index에 이름을 부여한 값을 말한다. 즉, 지정한 index 이름을 통해 불러올 수 있다.
iloc는 기본적으로 존재하는 정수형 위치 index를 말한다.
#원하는 행 지정하여 뽑아 내기
test_data = {'이름' : [1,2,3,4,5],
'창의' : [4,4,1,3,5],
'완성' : [4,1,2,1,3],
'사업' : [5,4,1,1,3]}
df = pd.DataFrame(test_data, index = ['1팀','2팀','3팀','4팀','5팀'])
print(df.loc[['1팀','2팀']])
print()
print(df.iloc[[0,1]])
이름 창의 완성 사업
1팀 1 4 4 5
2팀 2 4 1 4
이름 창의 완성 사업
1팀 1 4 4 5
2팀 2 4 1 4
# 슬라이싱으로 뽑아내기
test_data = {'이름' : [1,2,3,4,5],
'창의' : [4,4,1,3,5],
'완성' : [4,1,2,1,3],
'사업' : [5,4,1,1,3]}
df = pd.DataFrame(test_data, index = ['1팀','2팀','3팀','4팀','5팀'])
print(df.loc['1팀':'5팀'])
print()
print(df.iloc[0 : 5])
이름 창의 완성 사업
1팀 1 4 4 5
2팀 2 4 1 4
3팀 3 1 2 1
4팀 4 3 1 1
5팀 5 5 3 3
이름 창의 완성 사업
1팀 1 4 4 5
2팀 2 4 1 4
3팀 3 1 2 1
4팀 4 3 1 1
5팀 5 5 3 3
# 슬라이싱 활용 하기
test_data = {'이름' : [1,2,3,4,5],
'창의' : [4,4,1,3,5],
'완성' : [4,1,2,1,3],
'사업' : [5,4,1,1,3]}
df = pd.DataFrame(test_data, index = ['1팀','2팀','3팀','4팀','5팀'])
print(df.loc['1팀': : 2])
print()
print(df.iloc[0 : : 2])
이름 창의 완성 사업
1팀 1 4 4 5
3팀 3 1 2 1
5팀 5 5 3 3
이름 창의 완성 사업
1팀 1 4 4 5
3팀 3 1 2 1
5팀 5 5 3 3
원소 선택
DataFrame을 통해 2차원 데이터를 표 그래프로 만들어 봤다면, 이번엔 표에 이름을 붙여보자
기본 형태
변수. set_index('사용할 Series 선택', inplace = True)
. set_index() 메서드는 column을 index로 설정해 주는 함수로 key, index가 함께 들어간다.
test_data = {'이름':['상우','현정','문영','동엽','우제'],
'국어':[85,88,90,50,70],
'수학':[57,90,100,78,66],
'영어':[85,89,67,98,98],
'과학':[50,78,98,50,69],
'체육':[94,80,99,69,100]}
df=pd.DataFrame(test_data)
df.set_index('이름',inplace=True)
df
국어 수학 영어 과학 체육
이름
상우 85 57 85 50 94
현정 88 90 89 78 80
문영 90 100 67 98 99
동엽 50 78 98 50 69
우제 70 66 98 69 100
국어 수학 영어 과학 체육
이름
상우 85 57 85 50 94
현정 88 90 89 78 80
문영 90 100 67 98 99
동엽 50 78 98 50 69
우제 70 66 98 69 100
# 원소 하나 선택하기
print(df.loc[['상우'],['수학']])
print(df.iloc[[0],[1]])
수학
이름
상우 57
수학
이름
상우 57
# 원소 여러개 선택하기
print(df.loc[['문영','동엽'],['국어','체육']])
print(df.iloc[[2,3],[0,4]])
국어 체육
이름
문영 90 99
동엽 50 69
국어 체육
이름
문영 90 99
동엽 50 69