파이썬 판다스 Pandas 자료형태 Series와 DataFrame

지난 시간까지 넘파이 (Numpy) 라이브러리에 대해 학습하였고, 이제는 데이터 분석도구인 판다스 (Pandas) 공부로 이어간다.

앞에 파이썬 기초에 나오는 반복문 같은것만 하다말다 하는 것보다 이렇게 Numpy, Pandas 까지 한번 쭉 진도를 빼보는게 중요한 것 같다. 그래야 실제로 파이썬으로 어떻게 데이터 처리를 하고 실무에서 활용을 하는건지 조금이나마 감을 잡을 수 있다.

구글코랩 판다스 최신버전 설치

구글코랩 파이썬 학습환경에는 기본적으로 판다스가 설치되어 있지만, 본격적인 실습 전에 최신 버전으로 다운로드를 다시 해줄 수 있다.

import numpy as np
import pandas as pd
pd.__version__

'1.1.5'

🔺 그냥 판다스를 불러와서 버전을 확인해보면 1.1.5 라고 나오는데, (참고로 판다스를 하더라도 넘파이는 기본적으로 같이 불러와준다. 약방의 감초같은 존재이다.)

!pip install -U pandas 

import numpy as np
import pandas as pd
pd.__version__

'1.3.5'

🔺 install 다시한번 해주고 버전을 재확인하면 1.3.5라고 나온다. (211213 기준) 이렇게 해놓고 실습을 시작.

Pandas 특징

Numpy 에서 1차원 2차원 또는 고차원 배열을 만들어서 데이터 다루는 것을 했었는데, 왜 굳이 또 Pandas를 쓰는 것일까? Numpy가 강력한 기능들을 가지고 있다면 Pandas는 보다 실제 작업에 친화적인 형태를 띄고 있다.

✔️ Numpy는 보이지 않는 0부터 시작하는 zero base 숫자순서 인덱스만 가지고 있다 vs Pandas는 2가지 인덱스 종류를 가질 수 있다.

>> Integer Index : Numpy와 마찬가지로 보이지 않는 Zero Base Index

>> Label Index : 이름표를 붙이는 것처럼 새롭게 달아놓은, 눈에 보이는 명시적 Index 

✔️ 다양한 파일 포맷을 지원하는데, 특히 엑셀 CSV 확장자를 다룰 수 있어서 호환성이 뛰어나고 유용하다.

✔️ 그룹화 및 피봇 기능이 있다.

✔️ 인덱싱, 슬라이싱, 서브 지정 등이 가능

✔️ Time Series (시계열) 기능

이것저것 많은데 직접 해보면서 뭐가 좋다는 건지 익혀보자. 일단 오늘은 판다스의 기본적인 자료구조 형태에 대해서 알아본다.

Series : 1차원 배열 자료구조

Pandas 에서도 1차원 2차원 자료구조로 나뉘는데, 1차원 구조는 그동안 봐왔던 리스트라던지, 넘파이의 1차원 배열과 유사하다. 판다스에서 1차원 자료구조는 시리즈 (Series) 라고 한다.

s = pd.Series([10,20,30,40])
s

0    10
1    20
2    30
3    40
dtype: int64

🔺 시리즈 생성은 pd.Series 함수로 하며 ([  ]) 괄호 형태로 원소들을 넣어준다. 만든 시리즈를 불러오면 그냥 원소들만 나오는게 아니라 이렇게 0, 1, 2, 3 이라고 앞에 번호가 매겨져 있는것을 알 수 있다.

s2 = pd.Series(data=[10,20,30,40], index=['a', 'b', 'c', 'd'], dtype='float64')
s2

a    10.0
b    20.0
c    30.0
d    40.0
dtype: float64

🔺 괄호를 두개 써야했던 이유는 이 풀 형태의 생성코드를 보면 알 수 있다. 시리즈 함수는 인덱스와 자료형 등을 같이 지정해줄 수 있는데, 이 때 각각 [ ] 괄호를 쓴다.

여기서 인덱스를 a, b, c, d로 지정하였는데 이것은 앞서말한 Label Index가 된다. 이렇게 지정한다고 해서 0, 1, 2, 3 Integer Index가 존재하지 않는것은 아니다. 이름을 붙여놓은 인덱스도 있고 순서를 나타내는 보이지 않는 인덱스도 같이 존재한다.

시리즈 속성

s.shape, s.dtype, s.size, s.ndim

((4,), dtype('int64'), 4, 1)

🔺 시리즈에서도 넘파이와 같은 함수들로 속성을 확인할 수 있다. shape 으로 배열 형태 확인, dtype 으로 자료형, size로 원소개수, ndim 으로 몇차원인지 확인 등등이 있다.

s.index
RangeIndex(start=0, stop=4, step=1)

s.values
array([10, 20, 30, 40])

s2.index
Index(['a', 'b', 'c', 'd'], dtype='object')

s2.values
array([10., 20., 30., 40.])

🔺 index와 values 함수를 통해 인덱스와 데이터 요소들을 확인할 수 있다.

s1에서는 별도의 인덱스 지정이 없었으므로 0에서 4까지 (끝자리 미포함) 순차 인덱스임을 알려준다. s2에는 인덱스를 알파벳으로 별도로 매겨주었기에 위와같이 인덱스가 따로 나오고 dtype이 object로 뜬다.

DataFrame : 2차원 테이블 자료구조

이제 Pandas의 꽃(?) 2차원 테이블 자료구조인 DataFrame을 생성해보자.

df = pd.DataFrame(data=[[10,20,30], 
                        [40,50,60],
                        [70,80,90]])
df


    0   1   2
0    10  20  30
1    40  50  60
2    70  80  90

🔺 함수는 pd.DataFrame으로 사용하고 데이터 자체는 Numpy처럼 행렬 배열처럼 집어넣어주면 된다. 데이타 요소 부분은 data= 이라고 해도 되고 안해줘도 된다. DataFrame에 대소문자는 정확히 입력해야 한다.

DataFrame은 일단 보여지는거 자체가 행번호 열번호가 매겨져 있고 테이블 형태로 깔끔하게 나온다. 엑셀에서 작업하는 것과 유사하게 보여주어서 데이터를 보기가 편하다.

[##_Image|kage@YgerN/btrnN3gjclp/d0fOQGzQfOUqsXZlaSwYX0/img.png|CDM|1.3|{“originWidth”:492,”originHeight”:248,”style”:”widthContent”}_##]

🔺 블로그에선 코드창에 복사해놨지만 실제로 구글코랩 파이썬 작업환경에서는 이렇게 예쁘게 보임. 그리고 마우스 커서를 대면 행 단위로 하이라이트도 된다.

df2 = pd.DataFrame([[10,20,30],
                    [40,50,60],
                    [70,80,90]], index=['a', 'b', 'c'], columns=['A', 'B', 'C'])
df2


    A   B   C
a    10  20  30
b    40  50  60
c    70  80  90

🔺 데이터프레임에서는 인덱스와 컬럼을 각각 지정해줄 수 있다. 인덱스는 행번호 컬럼은 열번호가 된다. 앞서 말했듯이 이것들은 Label Index로 이름을 붙인 것이고 여기에 이제 보이지 않는 순번 인덱스는 여전히 존재해서 필요하면 써먹을 수 있다.

데이터프레임 속성

df2.shape, df2.ndim, df2.size
((3, 3), 2, 9)

🔺 numpy와 같이 shape으로 몇행몇열인지 알 수 있고, ndim 몇 차원인지, size 원소 개수 몇개인지 확인이 가능하다.

df2.index
Index(['a', 'b', 'c'], dtype='object')

df2.columns
Index(['A', 'B', 'C'], dtype='object')

df2.values
array([[10, 20, 30],
       [40, 50, 60],
       [70, 80, 90]])

🔺 여기서는 Index와 Columns를 각각 만들어 주었고 dtype이 객체인 형태로 Label Index가 있는 것으로 나타난다. values를 하면 내용물만 마치 numpy array 형태처럼 보여준다.

pd.DataFrame({'name':['Lee', 'Kim', 'Park'], 
              'age' : [27, 24, 30]})

    name    age
0    Lee     27
1    Kim     24
2    Park    30


names = pd.Series(['Lee', 'Kim', 'Park'], index=['a', 'b', 'c'])
ages = pd.Series([27, 24, 30], index=['a', 'b', 'c'])

df3 = pd.DataFrame({'name': names, 'age':ages})
df3

    name    age
a    Lee     27
b    Kim     24
c    Park    30

🔺 DataFrame을 생성할때 이렇게 Columns의 Label Index를 지정하고 거기에 들어갈 원소들을 입력해줄 수도 있다. 입력할 때 괄호 형태를 보면 { } 로 되어 있는데 이것은 Key : Value 쌍의 자료구조인 딕셔너리이다.

두번째 예시는 1차원 배열인 시리즈 변수명으로 각각 만들어주고, DataFrame에서 딕셔너리 형태로 불러올 때 Value 부분에다가 시리즈 변수명을 넣어준 경우이다. 이렇게 중간에 한번 거쳐서 하는것이 작업시 수정하거나 할 때 여러모로 편리하다.

참고 : 파이썬 기초 딕셔너리 (사전) 자료형태 복습

df3.dtypes

name    object
age      int64
dtype: object


df3.info()

<class 'pandas.core.frame.DataFrame'>
Index: 3 entries, a to c
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   name    3 non-null      object
 1   age     3 non-null      int64 
dtypes: int64(1), object(1)
memory usage: 72.0+ bytes

🔺 데이터프레임에서도 속성을 보는 dtype 함수를 쓸 수 있는데 여러개니까 dtypes 라고 쓴다. info로 이 데이터프레임이 가지는 정보도 볼 수 있는데 여기에 아예 dtype도 포함되어서 나온다.

다음 시간에는 판다스 Pandas에서 파일을 불러오는 방법에 대해 알아본다. Numpy에서는 제일 마지막에 했던 부분인데 Pandas는 가장 처음에 공부한다. 그만큼 엑셀로 작성된 raw data를 가져와서 가공하고 해석하는 것이 주요 기능이라는 것이다.