이번 장에서는 간단히 pandas 라이브러리란 무엇이고 pandas의 시리즈 type에 대해서 설명하겠다.
# Pandas
- 데이터 처리 및 분석을 위한 라이브러리
- 대용량 데이터를 안정적이면서도 간편하게 처리
- 서로 다른 데이터타입으로 열을 구성할 수 있음
- (참고) Numpy : 전체 배열 원소를 동일한 타입으로 제한
- 주요 기능
- 데이터 입출력: csv,excel,RDB 등 다양한 포맷의 데이터를 효율적으로 처리할 수 있는 형식을 사용
- 데이터 가공 : 분리, 결합, 계층, 피봇 등
- 통계 분석 처리
위와 같은 특징 때문에 데이터를 분석하기 위해서는 pandas 라이브러리의 설치는 기본이라고 할 수 있다.
pandas 설치는 import pandas as pd 를 첫 셀에 설치가 기본이다.
데이터 불러오는 것의 기본인 pd.read_csv() , pd.read_excel() 이 모두 pandas에 있는 모듈이다.
먼저 pandas에 있는 Series type 에 대해서 알아보자!
### 자료형
- Series
- 1차원 배열과 유사한 자료형
- 색인(index): 행 번호
- 각각의 데이터에 부여하는 속성으로 기본값은 0부터 1씩 증가하는 숫자 지정
- index 파라미터를 통해 새로운 값으로 변경 가능
- 리스트, 튜플 타입으로 새로운 값을 전달해야하며 다차원 자료형은 사용할 수 없음
- 전달하는 색인의 개수와 데이터의 개수가 일치해야 함
- 각각의 색인과 데이터가 매핑되어 있으므로 dictionary 자료형과 유사
- 여러가지 데이터 타입 사용 가능
## Series 속성
- 속성은 소괄호를 붙이지 않음
- index: series 객체의 인덱스 배열
- values: 데이터(값)의 배열
- name: series 객체의 이름
- dtype: 데이터 타입
- size: 데이터 개수(길이)
- shape: 구조 (행,열,차원)
s6= pd.Series({'a':100,'b':200,'c':300})
s6
#out
a 100
b 200
c 300
dtype: int64
s6 라는 Series로 예시를 들겠다.
s6.index
#out
Index(['a', 'b', 'c'], dtype='object')
s6.values
#out
array([100, 200, 300], dtype=int64)
dictionary의 key가 index로 들어가고 value값이 Series의 value값으로 들어가는 것을 알 수 있다.
이제 Series의 index를 변경하는 방법을 알아보도록 하겠다.
인덱스 새롭게 지정하기 위해선 시리즈객체.index = [a,b] 처럼 해야된다. 이 때 데이터타입은 리스트이어야 되고 가장 중요한 조건은 인덱스 개수와 일치하게 전달을 해야된다.
s6.index = [x,y,z]
s6
#out
x 100
y 200
z 300
dtype: int64
# 인덱스 객체의 아이템 수정: 일부 아이템에 대해서 수정 불가
s6.index[0]='A'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-36-8ed463802578> in <module>
1 # 인덱스 객체의 아이템 수정: 일부 아이템에 대해서 수정 불가
----> 2 s6.index[0]=['A']
~\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
3936
3937 def __setitem__(self, key, value):
-> 3938 raise TypeError("Index does not support mutable operations")
3939
3940 def __getitem__(self, key):
TypeError: Index does not support mutable operations
위와 같이 인덱스를 일부만 수정하는 것은 불가능하다.
이제 인덱싱을 알아보겠다.
## 인덱싱(Indexing)
- 하나의 특정 값을 선택하거나 변경
- 참조하는 인덱스: 기본 숫자 인덱스(RangeIndex). 라벨 인덱스
- 새로운 인덱스를 설정해도 기본 숫자 인덱스 사용 가능
이를 알아보기 위해 s8 이라는 series를 새로 생성하겠다.
# series 로 생성 하려는 데이터
# 서울 경기 부산 + 강원
idx=['서울','경기','부산','강원']
s8=pd.Series(data,index=idx)
s8
#out
서울 100.0
경기 200.0
부산 300.0
강원 NaN
dtype: float64
# series 인덱싱 문법: series객체[인덱스번호] 또는 series객체[인덱스라벨]
# 참조할 수 있는 인덱스 : 서울,0
s8[0]
#out
100.0
s8['서울']
#out
100.0
# 여러 개의 인덱스에 대한 값 조회: 멀티인덱싱 => 리스트로 전달
s8[[0,3]] # 또는
s8[['서울','강원']]
#out
서울 100.0
강원 0.0
dtype: float64
인덱스 번호나 인덱스 명으로 값을 조회할 수 있다.
series는 인덱스는 별도로 수정할 수는 없지만 값은 별도로 수정이 가능하다.
# 값 수정
# 인덱스: 일부 인덱스에 대해 인덱싱으로 수정 X
# s8.index[0]='t' => Error
# 데이터: 일부 값에 대해 인덱싱으로 수정 O
s8[3]=0
s8
#out
서울 100.0
경기 200.0
부산 300.0
강원 0.0
dtype: float64
다음으로 슬라이싱에 대해서 알아보겠다.
## 슬라이싱
- Series 객체[시작인덱스:끝인덱스:간격]
- 특정 범위의 값을 선택하거나 변경
- 기본 숫자 인덱스 또는 새로운 인덱스 모두 사용 가능
- 기본 숫자 인덱스를 사용해서 슬라이싱 할 때는 끝 인덱스 미포함
- 라벨 인덱스를 사용해서 슬라이싱 할 때 끝 인덱스까지 모두 포함
인덱싱과 슬라이싱은 큰 차이는 없이 값을 뽑아내는 것이라고 생각하면 된다.
예시를 위해 s1 시리즈를 생성한다.
s1 = pd.Series([10,20,30,40,50],index=list('abcde'))
s1
#out
a 10
b 20
c 30
d 40
e 50
dtype: int64
# 0, 1번 인덱스 조회
s1[:2]
#out
a 10
b 20
dtype: int64
# 인덱스 라벨 'a'에서 'b'까지 조회
s1['a':'b']
#out
a 10
b 20
dtype: int64
#a부터d까지 2개씩 건너 뛰면서
s1['a':'d':2]
#out
a 10
c 30
dtype: int64
슬라이싱은 범위로 나타낸다는 것을 알 수 있다. 그리고 간격을 정해줄 수도 있다.
## Series의 산술연산
- series 객체와 스칼라 값의 산술연산 => Broadcasting
- series 객체 간의 산술 연산
- 인덱스의 라벨이 동일한 것끼리 연산 수행, 공통으로 존재하지 않는 경우 NaN 반환
- 라벨이 없는 경우 차례대로 연산 수행, 개수가 동일하지 않는 경우 NaN 반환
- fill_value 인자를 통해 NaN이 아닌 특정 값으로 대체 가능
산술연산을 알아보기 위해 s2라는 또 다른 Series 타입을 생성하겠다.
# data: 10,20,30,40,50,60
# 라벨: acdefg
s2=pd.Series([10,20,30,40,50,60],index=list('acdefg'))
s2
#out
a 10
c 20
d 30
e 40
f 50
g 60
dtype: int64
s1+10
#out
a 11
b 12
c 13
d 14
dtype: int64
시리즈에 숫자만 연산시키면 스칼라값으로 연산이 된다는 것을 알 수 있다.
#series 객체간의 산술연산
s1+s2
#out
a 11.0
b NaN
c 23.0
d 34.0
e NaN
f NaN
g NaN
dtype: float64
s1 과 s2의 시리즈의 산술연산을 하면 라벨이 같은 것들만 연산이 되고 나머지는 결측치로 결과가 도출됨을 알 수 있다.
# fill_value 파라미터: 공통이 아닌 인덱스의 값에 NaN 대신 지정한 값을 사용
s1.add(s2,fill_value=0)
#out
a 11.0
b 2.0
c 23.0
d 34.0
e 40.0
f 50.0
g 60.0
dtype: float64
이처럼 산술연산 함수에 fill_value 파라미터를 적용하여 공통이 아닌 인덱스의 값에 결측치 대신 지정한 값 0을 사용하여 계산이 됨을 알 수 있다.
series의 이해를 돕기위해 연습문제 하나를 생성하여 풀어보자
1. 실습 데이터 생성: 1~100(미만)사이의 랜덤 정수 값을 26개 저장한 Series를 생성하고 A~Z까지의 알파벳으로 라벨링 설정하라
import numpy as np
data = np.random.randint(1,100,(26))
#아스키코드를 이용한 문자열 생성
# A : 65, Z=90 => chr() 아스키코드 기준으로 문자열로 변환
alphabet=[]
for code in range(65,91):
alphabet.append(chr(code))
data1=pd.Series(data,index=alphabet)
data1
#out
A 89
B 30
C 12
D 61
E 99
F 11
G 52
H 2
I 21
J 19
K 1
L 20
M 87
N 84
O 56
P 65
Q 79
R 3
S 22
T 13
U 43
V 54
W 76
X 12
Y 34
Z 41
dtype: int32
2.인덱스 라벨이 K항목의 값 출력
data1['K']
#out
1
3. 인덱스 라벨이 A,F,C 항목의 값 출력 (인덱싱)
data1[['A','F','C']]
#out
A 89
F 11
C 12
dtype: int32
4. 5번 인덱스부터 15번 인덱스까지의 항목 출력(슬라이싱)
data1[5:15]
#out
F 11
G 52
H 2
I 21
J 19
K 1
L 20
M 87
N 84
O 56
dtype: int32
5. 뒤에서 5개 항목 출력
data1.tail() #default 값이 5임
#out
V 54
W 76
X 12
Y 34
Z 41
dtype: int32
6. 생성한 시리즈의 항목의 개수 출력
len(data1)
#out
26
data1.size
#out
26
7. data 항목 값들의 평균보다 큰 항목만 출력
data1[data1>np.mean(data1)]
#out
A 89
D 61
E 99
G 52
M 87
N 84
O 56
P 65
Q 79
U 43
V 54
W 76
dtype: int32
8. data의 항목 값 중에서 50이 있는지 확인하여 있으면 True 없으면 False 출력
50 in data1.values
#out
False
in 함수를 통해 data1의 값에 50이 있는지를 체크하는 것이다.
9. data의 인덱스 라벨과 각 항목 값을 아래와 같이 출력
- 출력화면
- index: A, value: XX
for idx,values in data1.items():
print('index : {}, values: {}'.format(idx,values))
#out
index : A, values: 89
index : B, values: 30
index : C, values: 12
index : D, values: 61
index : E, values: 99
index : F, values: 11
index : G, values: 52
index : H, values: 2
index : I, values: 21
index : J, values: 19
index : K, values: 1
index : L, values: 20
index : M, values: 87
index : N, values: 84
index : O, values: 56
index : P, values: 65
index : Q, values: 79
index : R, values: 3
index : S, values: 22
index : T, values: 13
index : U, values: 43
index : V, values: 54
index : W, values: 76
index : X, values: 12
index : Y, values: 34
index : Z, values: 41
data1.items() 메소드를 실행시키면 <zip at 0x2a60735ee88> 이렇게 나오지만 괄호를 빼고 나오면 index 와 value가 나온다. data1.items()의 출력값에서 zip은 index와 value값이 합쳐진 것으로 zip 형태로 있다는 것을 의미한다. 나중에 설명하겠지만 지금은 알집 형태라고 생각하면 편할 것이다.
다음 장에서는 pandas의 꽃 dataframe 형태에 대해서 설명하겠다.
'Python > python 기초' 카테고리의 다른 글
Pandas - 3 (0) | 2020.02.23 |
---|---|
Pandas - 2 (0) | 2020.02.02 |
Numpy - 6 (2) | 2020.01.22 |
Numpy - 5 (0) | 2020.01.22 |
Numpy array - 4 (0) | 2020.01.07 |
댓글