TIL - Pandas (Part 1)

MinWoo Park·2021년 2월 20일
0

TIL

목록 보기
14/49
post-thumbnail

Today I Learned

매일 배운 것을 정리하며 기록합니다.
Pandas에 입문하여 자료구조, 인덱스 활용, 산술연산을 공부하였습니다.


Pandas

  • 표를 다룰 수 있게 도와주는 라이브러리
  • 데이터를 수집하고 정리하는데 최적화된 도구
  • 사용 예시
    - 파일 읽어오기: pandas.read_csv('/경로/파일명.csv')
    - 모양 확인하기: print(데이터.shape)
    - 컬럼 선택하기: 데이터[['컬럼명1', '컬럼명2', '컬럼명3']]
    - 컬럼 이름 출력하기: print(데이터.columns)
    - 맨 위 5개 관측치 출려하기: 데이터.head()
    - 맨 아래 5개 관측치 출력하기: 데이터.tail()

1. Pandas 자료구조

  • 서로 다른 여러 가지 유형의 데이터를 공통의 포맷으로 통합할 수 있도록 구조화된 데이터 형식인 시리즈와 데이터프레임을 제공
  • 시리즈(Series): 1차원 배열
  • 데이터프레임(DataFrame): 2차원 배열

1-1. 시리즈(Series)

  • 데이터가 순차적으로 나열된 1차원 배열의 형태
  • 인덱스와 데이터 값이 일대일 대응
  • 판다스 내장함수 Series()를 통해 파이썬 자료구조를 시리즈로 변환
  • ex)
import pandas as pd

dict_data = {'a': 1, 'b': 2, 'c': 3}

sr = pd.Series(dict_data)

print(type(sr))  # <class 'pandas.core.series.Series'>

print('\n')

print(sr)
# a    1
# b    2
# c    3
# dtype: int64

1-2. 데이터프레임(DataFrame)

  • 파이썬 대표 데이터 핸들링 라이브러리, 판다스의 핵심 객체
  • 행과 열로 만들어지는 2차원 배열 구조로 이루어져 있기 때문에 인간이 가장 이해하기 쉽고, 효율적으로 가공/처리 가능
  • 여러 개의 열벡터들이 같은 행 인덱스를 기준으로 줄지어 결합된 2차원 벡터 또는 행렬(matrix)
  • 판다스 내장함수 DataFrame()을 통해 파이썬 자료구조를 데이터프레임으로 변환
  • ex)
import pandas as pd

dict_data = {'c0': [1, 2, 3], 'c1': [4, 5, 6], 'c2': [
    7, 8, 9], 'c3': [10, 11, 12], 'c4': [13, 14, 15]}

df = pd.DataFrame(dict_data)

print(type(df))
print('\n')
print(df)

# <class 'pandas.core.frame.DataFrame'>


#    c0  c1  c2  c3  c4
# 0   1   4   7  10  13
# 1   2   5   8  11  14
# 2   3   6   9  12  15

행 인덱스/열 이름 설정

  • 데이터프레임 구조적 특성 때문에 2차원 배열 형태의 데이터를 데이터프레임으로 변환하기 쉬움
  • ex)
# pandas.DataFrame(2차원 배열, index=행 인덱스 배열, columns=열 이름 배열)

import pandas as pd

df = pd.DataFrame([['돌솥비빔밥', '짜장면', '스테이크'], ['김치볶음밥', '짬뽕', '피자']], index=[
                  '맛있는 순위 1', '맛있는 순위 2'], columns=['한식', '중식', '양식'])                 
print(df)
#              한식      중식    양식
# 맛있는 순위 1  돌솥비빔밥  짜장면  스테이크
# 맛있는 순위 2  김치볶음밥   짬뽕    피자

행 인덱스 변경

  • 데이터프레임의 행 인덱스와 열 이름 객체에 새로운 배열을 할당
    - DataFrame 객체.index = 새로운 행 인덱스 배열
    - DataFrame 객체.columns = 새로운 열 이름 배열

  • rename() 메서드를 사용하면 새로운 데이터프레임 객체를 반환받을 수 있음
    - DataFrame 객체.rename(index={기존 인덱스: 새 인덱스,...})
    - DataFrame 객체.rename(columns={기존 이름: 새 이름,...})


행/열 삭제

  • 행: drop()메서드를 사용하여 행을 삭제할 때는 축 옵션으로 axis=0 입력하거나, 생략
DataFrame 객체.drop(행 인덱스 또는 배열, axis=0)
  • 열: drop()메서드를 사용하여 열을 삭제할 떄는 axis=1을 입력하여 삭제
DataFrame 객체.drop(열 이름 또는 배열, axis=1)

행 선택

  • 인덱스 이름(index label): loc
    범위 지정 시 ['start': 'end'], start ~ end(end 포함)
	DataFrame 객체.loc['1번 행 이름']
	DataFrame 객체.loc['1번 행 이름':'3번 행 이름']
  • 정수형 위치 인덱스(integer position): iloc
    범위 지정 시 [start: end], start ~ end-1(end 미포함)
	DataFrame 객체.iloc[0]
	DataFrame 객체.iloc[0:3]

열 선택

  • 열 1개 선택(시리즈 생성):
DataFrame 객체["열 이름"] 또는 DataFrame 객체. 열 이름
  • 열 n개 선택(데이터프레임 생성):
DataFrame 객체[ [1,2, ...열n] ]
  • 범위 슬라이싱
DataFrame 객체.iloc[ 시작 인덱스 : 끝 인덱스 : 슬라이싱 간격 ]
  • 역순 인덱싱
DataFrame 객체.iloc[ : : -1 ] # 모든 행을 역순 정렬

원소 선택

  • 1개의 행과 2개 이상의 열을 선택하거나, 2개 이상의 행과 1개의 열을 선택하는 경우 시리즈 객체 반환

  • 2개 이상의 행과 2개 이상의 열을 선택하면 데이터프레임 객체 반환

  • 인덱스 이름

DataFrame 객체.loc[행 인덱스, 열 이름]
  • 정수 위치 인덱스
DataFrame 객체.iloc[행 번호, 열 번호]

열 추가

  • DataFrame 객체['열 이름'] = 데이터 값
  • ex)
import pandas as pd

exam_data = {'이름': ['김코딩', '박해커', '최고수'],
             '언어': ['JS', 'Python', 'C'],
             '경력': ['1년', '2년', '3년'],
             '취미': ['걷기', '독서', '등산'],
             '특기': ['양궁', '축구', '노래']}
             
df = pd.DataFrame(exam_data)
print(df)
print('\n')

df['특기'] = '코딩'
print(df)

#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  양궁
# 1  박해커  Python  2년  독서  축구
# 2  최고수       C  3년  등산  노래

#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  코딩
# 1  박해커  Python  2년  독서  코딩
# 2  최고수       C  3년  등산  코딩

행 추가

  • DataFrame.loc['행 이름'] = 데이터 값 (또는 배열)
  • 데이터 값을 넣는 경우는 행의 모든 원소에 같은 값이 추가됨
  • 배열을 넣는 경우 배열의 순서대로 열 위치에 값이 추가됨
import pandas as pd

exam_data = {'이름': ['김코딩', '박해커', '최고수'],
             '언어': ['JS', 'Python', 'C'],
             '경력': ['1년', '2년', '3년'],
             '취미': ['걷기', '독서', '등산'],
             '특기': ['양궁', '축구', '노래']}

df = pd.DataFrame(exam_data)
print(df)
print('\n')

df.loc[3] = '행 추가'
print(df)
print('\n')

df.loc[4] = ['이박사', 'Java', '20년', '알고리즘 풀기', '요리']
print(df)

#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  양궁
# 1  박해커  Python  2년  독서  축구
# 2  최고수       C  3년  등산  노래


#      이름      언어    경력    취미    특기
# 0   김코딩      JS    1년    걷기    양궁
# 1   박해커  Python    2년    독서    축구
# 2   최고수       C    3년    등산    노래
# 3  행 추가    행 추가  행 추가  행 추가  행 추가


#      이름      언어    경력       취미    특기
# 0   김코딩      JS    1년       걷기    양궁
# 1   박해커  Python    2년       독서    축구
# 2   최고수       C    3년       등산    노래
# 3  행 추가    행 추가  행 추가     행 추가  행 추가
# 4   이박사    Java   20년  알고리즘 풀기    요리

원소 값 변경

  • DataFrame 객체의 일부분 또는 원소를 선택 = 새로운 값
import pandas as pd

exam_data = {'이름': ['김코딩', '박해커', '최고수'],
             '언어': ['JS', 'Python', 'C'],
             '경력': ['1년', '2년', '3년'],
             '취미': ['걷기', '독서', '등산'],
             '특기': ['양궁', '축구', '노래']}

df = pd.DataFrame(exam_data)
df.set_index('이름', inplace=True)
print(df)
print('\n')

df.iloc[0][2] = '달리기'
print(df)
print('\n')

df.loc['박해커']['취미'] = '퍼즐'
print(df)
print('\n')

df.loc['박해커', '취미'] = '낚시'
print(df)

#          언어  경력  취미  특기
# 이름                     
# 김코딩      JS  1년  걷기  양궁
# 박해커  Python  2년  독서  축구
# 최고수       C  3년  등산  노래


#          언어  경력   취미  특기
# 이름                      
# 김코딩      JS  1년  달리기  양궁
# 박해커  Python  2년   독서  축구
# 최고수       C  3년   등산  노래


#          언어  경력   취미  특기
# 이름                      
# 김코딩      JS  1년  달리기  양궁
# 박해커  Python  2년   퍼즐  축구
# 최고수       C  3년   등산  노래


#          언어  경력   취미  특기
# 이름                      
# 김코딩      JS  1년  달리기  양궁
# 박해커  Python  2년   낚시  축구
# 최고수       C  3년   등산  노래

행, 열의 위치 바꾸기

  • 선형대수학의 전치행렬과 같은 개념
  • DataFrame 객체.transpose()
  • DataFrame 객체.T
import pandas as pd

exam_data = {'이름': ['김코딩', '박해커', '최고수'],
             '언어': ['JS', 'Python', 'C'],
             '경력': ['1년', '2년', '3년'],
             '취미': ['걷기', '독서', '등산'],
             '특기': ['양궁', '축구', '노래']}

df = pd.DataFrame(exam_data)
print(df)
print('\n')

df.transpose()
print(df)
print('\n')

df.T
print(df)
print('\n')

#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  양궁
# 1  박해커  Python  2년  독서  축구
# 2  최고수       C  3년  등산  노래


#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  양궁
# 1  박해커  Python  2년  독서  축구
# 2  최고수       C  3년  등산  노래


#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  양궁
# 1  박해커  Python  2년  독서  축구
# 2  최고수       C  3년  등산  노래

2. 인덱스의 활용

특정 열을 행 인덱스로 설정

  • DataFrame 객체.set_index( ['열 이름'] 또는 '열 이름')
import pandas as pd

exam_data = {'이름': ['김코딩', '박해커', '최고수'],
             '언어': ['JS', 'Python', 'C'],
             '경력': ['1년', '2년', '3년'],
             '취미': ['걷기', '독서', '등산'],
             '특기': ['양궁', '축구', '노래']}

df = pd.DataFrame(exam_data)
print(df)
print('\n')

ndf = df.set_index(['이름'])
print(ndf)
print('\n')

ndf2 = df.set_index(['언어'])
print(ndf2)
print('\n')

#     이름      언어  경력  취미  특기
# 0  김코딩      JS  1년  걷기  양궁
# 1  박해커  Python  2년  독서  축구
# 2  최고수       C  3년  등산  노래


#          언어  경력  취미  특기
# 이름                     
# 김코딩      JS  1년  걷기  양궁
# 박해커  Python  2년  독서  축구
# 최고수       C  3년  등산  노래


#          이름  경력  취미  특기
# 언어                     
# JS      김코딩  1년  걷기  양궁
# Python  박해커  2년  독서  축구
# C       최고수  3년  등산  노래

행 인덱스 재배열 - reindex()

  • 새로운 배열로 행 인덱스를 재지정: DataFrame 객체.reindex( 새로운 인덱스 배열 )
  • 새롭게 추가하는 행 인덱스에 해당하는 열은 NaN값이 되므로 유효한 값으로 채우려면 fill_value 옵션을 사용한다.
import pandas as pd

dict_data = {'c': [1, 2, 3], 'c1': [4, 5, 6], 'c2': [
    7, 8, 9, ], 'c3': [10, 11, 12], 'c4': [13, 14, 15]}

df = pd.DataFrame(dict_data, index=['r0', 'r1', 'r2'])
print(df)
print('\n')
#     c  c1  c2  c3  c4
# r0  1   4   7  10  13
# r1  2   5   8  11  14
# r2  3   6   9  12  15

new_index = ['r0', 'r1', 'r2', 'r3', 'r4']
ndf = df.reindex(new_index)
print(ndf)
print('\n')
#       c   c1   c2    c3    c4
# r0  1.0  4.0  7.0  10.0  13.0
# r1  2.0  5.0  8.0  11.0  14.0
# r2  3.0  6.0  9.0  12.0  15.0f
# r3  NaN  NaN  NaN   NaN   NaN
# r4  NaN  NaN  NaN   NaN   NaN

ndf2 = df.reindex(new_index, fill_value=0)
print(ndf2)
#     c  c1  c2  c3  c4
# r0  1   4   7  10  13
# r1  2   5   8  11  14
# r2  3   6   9  12  15
# r3  0   0   0   0   0
# r4  0   0   0   0   0

행 인덱스 초기화 - reset_index()

  • 행 인덱스를 정수형 위치 인덱스로 초기화함
  • 기존 행 인덱스는 열로 이동시킴
import pandas as pd

dict_data = {'c': [1, 2, 3], 'c1': [4, 5, 6], 'c2': [
    7, 8, 9, ], 'c3': [10, 11, 12], 'c4': [13, 14, 15]}

df = pd.DataFrame(dict_data, index=['r0', 'r1', 'r2'])
print(df)
print('\n')
#     c  c1  c2  c3  c4
# r0  1   4   7  10  13
# r1  2   5   8  11  14
# r2  3   6   9  12  15

ndf = df.reset_index()
print(ndf)
#   index  c  c1  c2  c3  c4
# 0    r0  1   4   7  10  13
# 1    r1  2   5   8  11  14
# 2    r2  3   6   9  12  15

행 인덱스를 기준으로 데이터프레임 정렬 - sort_index()

  • ascending 옵션으로 오름차순 또는 내림차순 설정
import pandas as pd

dict_data = {'c': [1, 2, 3], 'c1': [4, 5, 6], 'c2': [
    7, 8, 9, ], 'c3': [10, 11, 12], 'c4': [13, 14, 15]}

df = pd.DataFrame(dict_data, index=['r0', 'r1', 'r2'])
print(df)
print('\n')
#     c  c1  c2  c3  c4
# r0  1   4   7  10  13
# r1  2   5   8  11  14
# r2  3   6   9  12  15

ndf = df.sort_index(ascending=False)
print(ndf)
#     c  c1  c2  c3  c4
# r2  3   6   9  12  15
# r1  2   5   8  11  14
# r0  1   4   7  10  13

3. 산술연산

  • 판다스 객체의 산술연산은 내부적으로 3단계 프로세스를 거침
    1.행/열 인덱스를 기준으로 모든 원소를 정렬
    2.동일한 위치에 있는 원소끼리 일대일 대응
    3.일대일 대응 되는 원소끼리 연산 처리, 이때 대응되는 원소 없으면 NaN으로 처리

  • 시리즈와 숫자 연산: Series + 연산자(+, -, *, /) + 숫자

  • 시리즈와 시리즈: Series1 + 연산자(+, -, *, /) + Series2

  • 연산 메소드(add, sub, mul, div): ex) Series.add(series2)

  • 객체 사이에 공통 인덱스가 없거나 NaN이 포함된 경우 연산 결과는 NaN으로 반환,
    이떄 fill_value옵션을 사용하면 방지할 수 있음
    ex) Series.sub(series2, fill_value=0)

  • 데이터프레임은 여러 시리즈가 모인 것이므로 동일하며 시리즈 연산의 확장으로 이해하는 것이 좋음


Reference : 오승환, 『파이썬 머신러닝 판다스 데이터 분석』, 정보문화사 (2019), p002-055.

profile
물음표를 느낌표로 바꾸는 순간을 사랑하는 개발자입니다.

0개의 댓글