본문 바로가기
Python/python 기초

Pandas - 1

by winston1214 2020. 1. 31.
반응형

이번 장에서는 간단히 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

댓글