#01-Pandas(판다스) 기본 자료구조
Jan 11, 2021

Pandas(판다스) 는 막강한 오픈소스 데이터 분석 도구 입니다. Pandas는 업무자동화, 크롤링(Crawling), 데이터베이스 입출력, 시계열 데이터분석, 시각화 등등 다양한 분야에 활용할 수 있는 방대한 기능을 갖추고 있습니다. Pandas의 DataFrame은 Microsoft사의 엑셀과 유사한 인터페이스를 지원하면서도 엑셀로는 실행하기 다소 까다롭고 복잡한 Task를 매우 쉽고 간결한 코드로 해결할 수 있는 장점을 가지고 있습니다. 뿐만아니라, scikit-learn과 같은 머신러닝 패키지 그리고 TensorFlow, Keras, PyTorch와 같은 딥러닝 프레임워크와 호환성이 뛰어나기 때문에 데이터분석가로부터 사랑받고 있는 패키지입니다.

데이터분석가 그리고 머신러닝 엔지니어가 되기 위해서는 반드시 알아야하는 Pandas를 익히기 위한 튜토리얼입니다.

이번 에피소드에서는 Pandas의 자료구조에 대하여 알아보겠습니다.

Pandas 튜토리얼 EP01 - 자료구조

from IPython.display import Image
import numpy as np
Image('https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Pandas_logo.svg/1280px-Pandas_logo.svg.png', width=500)

Pandas

개요

관계형 또는 레이블이 된 데이터로 쉽고 직관적 으로 작업할 수 있도록 설계되었고, 빠르고, 유연한 데이터 구조를 제공하는 Python 패키지입니다.

또한, 어떤 언어로도 사용할 수 있는 가장 강력하고 유연한 오픈 소스 데이터 분석 / 조직 도구입니다.

Pandas는 다음의 종류의 데이터에 적합한 분석 패키지입니다.

  • SQL 테이블 또는 Excel 스프레드 시트에서와 같은 열과 행으로 이루어진 테이블 형식 데이터
  • 정렬되고 정렬되지 않은 시계열 데이터
  • 다른 형태의 관찰 / 통계 데이터 세트

Pandas 공식 문서

공식 문서는 다음 링크에서 확인할 수 있습니다.

alias(별칭)와 버전

import pandas
pandas.__version__
'0.25.3'

pandas는 pd의 alias를 사용합니다.

import pandas as pd
pd
<module 'pandas' from '/opt/conda/lib/python3.6/site-packages/pandas/__init__.py'>
pd.__version__
'0.25.3'

Series

Pandas의 Series는 1차원 배열로서 다음의 특징을 가집니다.

  • 데이터를 담는 차원 배열 구조를 가집니다.
  • 인덱스(index)를 사용 가능합니다.
  • 데이터 타입을 가집니다. (dtype)

Series의 생성

numpy array로 생성한 경우

arr = np.arange(100, 105)
arr
array([100, 101, 102, 103, 104])
s = pd.Series(arr)
s
0    100
1    101
2    102
3    103
4    104
dtype: int64

dtype을 지정한 경우

s = pd.Series(arr, dtype='int32')
s
0    100
1    101
2    102
3    103
4    104
dtype: int32

list로 생성한 경우

s = pd.Series(['부장', '차장', '대리', '사원', '인턴'])
s
0    부장
1    차장
2    대리
3    사원
4    인턴
dtype: object

다양한 타입(type)의 데이터를 섞은 경우

Series에 다양한 데이터 타입의 데이터로 생성시, object 타입으로 생성됩니다.

s = pd.Series([91, 2.5, '스포츠', 4, 5.16])
s
0      91
1     2.5
2     스포츠
3       4
4    5.16
dtype: object

index

# 샘플데이터
s = pd.Series(['부장', '차장', '대리', '사원', '인턴'])
s
0    부장
1    차장
2    대리
3    사원
4    인턴
dtype: object

기본 index는 0부터 숫자형 index가 부여됩니다.

s
0    부장
1    차장
2    대리
3    사원
4    인턴
dtype: object

기본 부여된 index로 값을 조회할 수 있습니다.

(indexing / slicing 은 이후에 좀 더 자세히 다룹니다.)

s[0]
'부장'

.index를 출력하면 RangeIndex로 표기됨을 확인할 수 있는데, 기본 부여된 index는 0~ 순차적으로 부여되기 때문입니다.

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

내가 원하는 index지정할 수 있습니다.

s = pd.Series(['마케팅', '경영', '개발', '기획', '인사'], index=['a', 'b', 'c', 'd', 'e'])
s
a    마케팅
b     경영
c     개발
d     기획
e     인사
dtype: object

새롭게 부여된 index로 접근 가능합니다.

s['c']
'개발'

하지만, 기본 부여된 숫자형 index로도 접근 가능합니다.

s[2]
'개발'

Series.index로도 index를 지정할 수 있습니다. 단, 지정하는 index의 갯수가 데이터의 갯수와 맞아야 합니다.

s.index = list('abcde')
s.index
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

values

values는 Series 데이터 값(value)만 numpy array 형식으로 가져 옵니다.

s.values
array(['마케팅', '경영', '개발', '기획', '인사'], dtype=object)

ndim - 차원

Series는 1차원 자료구조이기 때문에 ndim 출력시 1이 출력됩니다.

s.ndim
1

shape

shape은 데이터의 모양(shape)을 알아보기 위하여 사용하는데, Series의 shape은 데이터의 갯수를 나타냅니다.

튜플(tuple) 형식으로 출력됩니다.

s.shape
(5,)

NaN (Not a Number)

Pandas에서 NaN 값은 비어있는 결측치 데이터를 의미합니다.

임의로 비어있는 값을 대입하고자 할 때는 numpy의 nan (np.nan)을 입력합니다.

s = pd.Series(['선화', '강호', np.nan, '소정', '우영'])
s
0     선화
1     강호
2    NaN
3     소정
4     우영
dtype: object

연습문제

다음과 같은 Series를 생성해 주세요

  • s1 변수에 Series를 생성합니다.
  • dtype은 'float32'가 출력 되도록 합니다.
# 코드를 입력해 주세요
s1 = pd.Series(np.arange(50, 55), dtype='float32')
s1
0    50.0
1    51.0
2    52.0
3    53.0
4    54.0
dtype: float32

다음과 같은 Series를 생성해 주세요

  • s2 변수에 Series를 생성합니다.
# 코드를 입력해 주세요
s2 = pd.Series(['apple', np.nan, 'banana', 'kiwi', 'gubong'], index=list('가나다라마'))
s2
가     apple
나       NaN
다    banana
라      kiwi
마    gubong
dtype: object

indexing

s = pd.Series(['손흥민', '김연아', '박세리', '박찬호', '김연경'], index=['a', 'b', 'c', 'd', 'e'])
s
a    손흥민
b    김연아
c    박세리
d    박찬호
e    김연경
dtype: object

index는 기본 부여된 숫자형 index와 내가 새롭게 지정한 index 둘 다 조회 가능합니다.

s[1]
'김연아'
s['b']
'김연아'

fancy indexing

fancy indexing은 index를 선택하여 list로 정의하고, 선택한 index list로 indexing 하는 방법입니다.

s[['a','c']]
a    손흥민
c    박세리
dtype: object
i = ['a', 'c']
s[i]
a    손흥민
c    박세리
dtype: object

boolean indexing

boolean index은 index list 에서 True인 index 만 선택합니다.

주의해야할 점은 반드시 boolean index list의 갯수와 Series의 갯수가 맞아야 합니다.

s[[True, True, False, False, True]]
a    손흥민
b    김연아
e    김연경
dtype: object
i = [True, True, False, False, True]
s[i]
a    손흥민
b    김연아
e    김연경
dtype: object

조건을 걸어서 boolean index list를 먼저 만들어 준 뒤 대입할 수 있습니다.

s = pd.Series([29, 99, np.nan, 11, 56], index=['a', 'b', 'c', 'd', 'e'])
s
a    29.0
b    99.0
c     NaN
d    11.0
e    56.0
dtype: float64
s > 50
a    False
b     True
c    False
d    False
e     True
dtype: bool
s[s > 50]
b    99.0
e    56.0
dtype: float64

결측치 (NaN) 값 처리

isnull()isna()NaN 값을 찾는 함수 입니다.

isnull()isna()는 결과가 동일합니다.

s.isnull()
a    False
b    False
c     True
d    False
e    False
dtype: bool
s.isna()
a    False
b    False
c     True
d    False
e    False
dtype: bool

이를 boolean indexing에 적용해볼 수 있습니다.

s[s.isnull()]
c   NaN
dtype: float64
s[s.isna()]
c   NaN
dtype: float64

notnull()은 NaN값이 아닌, 즉 비어있지 않은 데이터를 찾는 함수 입니다.

s.notnull()
a     True
b     True
c    False
d     True
e     True
dtype: bool
s[s.notnull()]
a    29.0
b    99.0
d    11.0
e    56.0
dtype: float64

slicing

(주의) 숫자형 index로 접근할 때는 뒷 index가 포함되지 않습니다.

s[1:3]
b    99.0
c     NaN
dtype: float64

새롭게 지정한 인덱스는 시작 index와 끝 index 모두 포함합니다.

s['b':'c']
b    99.0
c     NaN
dtype: float64

DataFrame

pd.DataFrame

  • 2차원 데이터 구조 (Excel 데이터 시트를 생각하시면 됩니다)
  • 행(row), 열(column)으로 구성되어 있습니다.
  • 각 열(column)은 각각의 데이터 타입 (dtype)을 가집니다.

생성

list 를 통한 생성할 수 있습니다. DataFrame을 만들 때는 2차원 list를 대입합니다.

pd.DataFrame([[1, 2, 3], 
              [4, 5, 6], 
              [7, 8, 9]])
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9

아래 예제와 같이 columns를 지정하면, DataFrame의 각 열에 대한 컬럼명이 붙습니다.

pd.DataFrame([[1, 2, 3], 
              [4, 5, 6], 
              [7, 8, 9]], columns=['가', '나', '다'])
0 1 2 3
1 4 5 6
2 7 8 9

dictionary를 통한 생성도 가능합니다.

편리한 점은 dictionary의 key 값이 자동으로 column 명으로 지정됩니다.

data = {
    'name': ['Kim', 'Lee', 'Park'], 
    'age': [24, 27, 34], 
    'children': [2, 1, 3]
}
pd.DataFrame(data)
name age children
0 Kim 24 2
1 Lee 27 1
2 Park 34 3

속성

DataFrame은 다음의 속성을 가집니다.

  • index: index (기본 값으로 RangeIndex)
  • columns: column 명
  • values: numpy array형식의 데이터 값
  • dtypes: column 별 데이터 타입
  • T: DataFrame을 전치(Transpose)
data = {
    'name': ['Kim', 'Lee', 'Park'], 
    'age': [24, 27, 34], 
    'children': [2, 1, 3]
}

df = pd.DataFrame(data)
df
name age children
0 Kim 24 2
1 Lee 27 1
2 Park 34 3
df.index
RangeIndex(start=0, stop=3, step=1)
df.columns
Index(['name', 'age', 'children'], dtype='object')
df.values
array([['Kim', 24, 2],
       ['Lee', 27, 1],
       ['Park', 34, 3]], dtype=object)
df.dtypes
name        object
age          int64
children     int64
dtype: object
df.T
0 1 2
name Kim Lee Park
age 24 27 34
children 2 1 3

index 지정

df
name age children
0 Kim 24 2
1 Lee 27 1
2 Park 34 3
df.index = list('abc')
df
name age children
a Kim 24 2
b Lee 27 1
c Park 34 3

(참고) DataFrame의 indexing / slicing은 나중에 세부적으로 다루도록 하겠습니다.

column 다루기

DataFrame에 key 값으로 column의 이름을 지정하여 column을 선택할 수 있습니다.

1개의 column을 가져올 수 있으며, 1개의 column 선택시 Series가 됩니다.

df['name']
a     Kim
b     Lee
c    Park
Name: name, dtype: object
type(df['name'])
pandas.core.series.Series

2개 이상의 column 선택은 fancy indexing으로 가능합니다.

df[['name', 'children']]
name children
a Kim 2
b Lee 1
c Park 3

(참고) column에 대한 slicing도 가능 하지만 이 부분도 나중에 다루도록 하겠습니다.

rename으로 column명 변경 가능합니다.

DataFrame.rename(columns={'바꾸고자 하는 컬럼명': '바꿀 컬럼명'})

df.rename(columns={'name': '이름'})
이름 age children
a Kim 24 2
b Lee 27 1
c Park 34 3
df.rename({'name': '이름'}, axis=1)
이름 age children
a Kim 24 2
b Lee 27 1
c Park 34 3

inplace=True 옵션으로 변경사항을 바로 적용할 수 있습니다.

df.rename(columns={'name': '이름'}, inplace=True)
df
이름 age children
a Kim 24 2
b Lee 27 1
c Park 34 3

연습문제

다음의 DataFrame을 생성하세요

  • 생성된 DataFrame은 df 변수에 할당합니다.
# 코드를 입력해 주세요
data = {
    'food': ['KFC', 'McDonald', 'SchoolFood'], 
    'price': [1000, 2000, 2500], 
    'rating': [4.5, 3.9, 4.2]
}

df = pd.DataFrame(data)
df
food price rating
0 KFC 1000 4.5
1 McDonald 2000 3.9
2 SchoolFood 2500 4.2

food 컬럼과 rating 컬럼만 선택하여 출력하세요

# 코드를 입력해 주세요
df[['food', 'rating']]
food rating
0 KFC 4.5
1 McDonald 3.9
2 SchoolFood 4.2

food 컬럼명을 place로 컬럼명을 변경해 주세요

# 코드를 입력해 주세요
df.rename(columns={'food': 'place'}, inplace=True)
df
place price rating
0 KFC 1000 4.5
1 McDonald 2000 3.9
2 SchoolFood 2500 4.2


관련 글 더보기

- #04-Pandas(판다스) 통계

- #03-Pandas(판다스) 데이터프레임(DataFrame) 조회, 정렬(sort), 조건필터(loc, iloc)

- #02-Pandas(판다스) 파일 입출력 - Excel, CSV

- 국민연금 데이터를 활용한 연봉추정 분석

- 나라장터 입찰공고 데이터 분석 및 머신러닝 예측

데이터 분석, 머신러닝, 딥러닝의 대중화를 꿈 꿉니다.