18년 서울 Data Science 스터디
개요[편집]
- 2018년 하반기에 진행하는 데이터사이언스 스터디.
- 기간 (총 횟수) : 2018년 10월부터 2018년 12월까지(8 - 12)
- 장소 : 서울 강남 일대
- 교재 : 처음 배우는 데이터 과학
| 참가자 | ||
|---|---|---|
| 스터디장 | 홍길환 | |
| 참가자 | 배준현 | |
| 홍찬양 | ||
| 정동우 | ||
| 이승윤 | ||
| 최주영 | ||
| 박정호 | ||
모임 기록[편집]
1주차[편집]
- 날짜 : 10/13
- 참석자 : 7
- 진행한 내용 : 오리엔테이션, 교재소개, Python 설정, Pycharm(IDE) 설정, PIP 활용
- 과제 : 데이터 과학에 필요한 패키지(이승윤)
세부 진행내용[편집]
- ubuntu나 linux 등에서는 기본적으로 python3가 리눅스가 설치되면서 함께 내장되어 있습니다.
- 최신 버전인 3.7 버전으로도 업그레이드가 가능합니다.
- 하지만 3.6 버전으로도 진행이 가능하여, 3.6 버전에서 스터디를 진행하겠습니다.
user@ubuntu:~$ python3 --version Python 3.6.6
- Ubuntu에 Python 3.6 환경에서 PyCharm 설치 및 설정
- 터미널에 아래 명령어를 입력
sudo apt install snapd snapd-xdg-open
- 설치가 정상적으로 된 후, 다음 과정을 거쳐 PyCharm을 설치합니다.
- 개인용을 설치 할 예정이므로, "--classic" 버전을 설치해주세요.
sudo snap install pycharm-community --classic
- 정상적으로 설치가 된 경우 터미널에 아래와 같이 입력을 했을 때 다음과 같은 결과가 나옵니다.
user@ubuntu:~$ sudo snap install pycharm-community --classic pycharm-community 2018.2.4 from jetbrains✓ installed
- pip을 활용한 파이썬 라이브러리 설치 (링크로 대체)
- [PyCharm pip 명령어 대신 파이참을 이용해서 파이썬 패키지 모듈 설치하기]
- Pycharm 실행해보기
- 파일:Py.png
- pycharm classic ide의 아이콘을 클릭합니다.
- 실행이 되면 처음에는 기본 설정대로만 다음을 클릭합니다.
- 파일:Py2.png
- 새 프로젝트 생성
- 파일:Py3.png
- 새 파일 생성
- 새로 만든 프로젝트 명에서 마우스 오른쪽 버튼을 누르고 new에서 python file이라고 되어 있는 곳을 클릭하고 임의의 파이썬 파일명을 입력합니다.
- 아래와 같은 코드를 입력하신 후, "run"을 눌러주세요.
- 파일:Py.png
print("Hello, World!")
- 실습 - 라이브러리를 활용하여 그래프(Plot) 그려보기
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 10, 100) plt.plot(x, np.sin(x)) plt.plot(x, np.cos(x)) plt.show()
2주차[편집]
- 날짜 : 10/20
- 참석자 : 8
- 진행한 내용 : 데이터 과학 관련 패키지 소개, 데이터 과학 관련 파이썬 기초 문법과 활용 소개
- 과제 : 데이터 과학에 필요한 파이썬 문법
세부 진행내용[편집]
- 이번 주 과제 발표는 이승윤님이 해주셨습니다.
- 발표안은 데이터 과학 관련 파이썬 라이브러리입니다.
- 데이터 과학의 구성 요소
- 데이터 수집
- 데이터 분석
- 데이터 시각화
- 데이터 과학의 구성요소
- 데이터 과학은 크게 세 가지 구성 요소로 나눌 수 있습니다.
- 수집
- 분석
- 시각화
- 데이터 수집에 사용되는 라이브러리에 대해서 알아보기로 합니다.
- 데이터 수집의 방법 중에 하나는 웹 크롤링이 있습니다.
- 크롤링이란 웹 페이지의 자원을 읽어와 이용할 수 있도록 하는 것입니다.
- [1] [크롤링 참고 자료] 파이썬으로 크롤링하기
- requests
- html 획득에 사용됩니다.
- 원하는 웹 사이트에 requests를 날려 html을 받을 수 있는 라이브러리 입니다.
- [2] [requests] requests simple 참고 자료
- beautifulsoup
- beautifulsoup는 html 파싱에 사용된다.
- html 안에 원하는 태그를 가져 올 수 있는 find(), find_all()이 있습니다.
- 태그 안의 모든 문자열을 하나의 문자열로 만들어 반환 해주는 get_text() 등의
함수를 이용하여 html 코드를 간단하게 분석할 수도 있습니다.
- [3] [beautifulsoup사용법 참고 자료] beautifulsoup 사용법 링크입니다.
- 데이터 분석
- 데이터 분석과 가공 (pandas)
- 데이터를 분석하고 가공할 수 있습니다.
- [4] [pandas 관련 발표 링크] pandas 라이브러리에 대한 설명 자료입니다.
- pandas
- 데이터 분류된 데이터와 관계형 데이터를 직관적으로 처리할 수 있도록 하는 라이브러리 입니다.
- 1차원 자료구조인 Series, 2차원 자료구조인 DataFrame, 그리고 3차원 자료구조인 Panel
총 세 가지 자료구조를 지원합니다.
빠르고 쉬운 데이터 조작을 할 수 있는 점이 특징입니다.
- numpy
- 수학적, 과학적 데이터 분석에 용이한 라이브러리 입니다.
- 파이썬의 기본 자료구조보다 빠르고 효율적인 다차원배열 객체 n-array를 제공합니다.
- 배열 원소를 다루거나 배열간의 수학계산을 수행하는 함수,
선형대수의 계산, 푸리에 변환, 난수 발생기 같은 수치와 관련된 다양한 기능을 제공합니다.
- 데이터 시각화
- 분석, 가공한 데이터를 시각화할 수 있습니다. 파이썬 시각화 라이브러리로는 matplotlib가 있습니다.
- [5] [matplotlib 시각화 발표 참고 자료]
matplotlib
- 데이터 시각화에 사용되는 라이브러리 입니다.
- 2차원 선 그래프, 막대 그래프, 원형 그래프, 히스토그램은 물론 3차원 그래프까지
데이터를 다양한 형태로 시각화 할 수 있는 라이브러리 입니다.
[세부 참고 영어 문서] Better web scraping in Python with Selenium, Beautiful Soup, and pandas
- [7] [세부 참고 영어 문서 2]
Web Scraping in Python using Scrapy
- 감사합니다.
3주차[편집]
- 날짜 : 10/27
- 참석자 : 5
- 진행한 내용 : 데이터 과학에 필요한 파이썬 문법
- 과제 : matplotlib와 dpandas 문법과 csv를 이용하여 심플한 데이터 분석
세부 진행내용[편집]
- 파이썬 프로그램 실행 방법
- 인터프리터 프롬프트에서 실행
>>> print("hello world")
hello world
>>>
- 소스 파일을 사용하여 실행
- 예) hello.py 파일 생성 -> print("hello world") 입력 -> 터미널창에서 python3 hello.py 실행
- 실행 예시
vim hello.py
python3 hello.py
cat hello.py
#!/usr/bin/python3
print("hello world")
- 편집기의 종류 : vim, emacs, pycharm
- 문법강조 기능, 들여쓰기 기능 지원
- 파이썬 문법
- 주석
- 주석 기호
#, """
- 주석 사용 케이스
- 미리 가정하고 넘어간 것들에 대한 설명
- 중요한 결정 사항에 대한 설명
- 중요한 세부 사항에 대한 설명
- 해결하고자 하는 문제에 대한 설명
- 앞으로 극복하고자 하는 문제들에 대한 설명 등등.
- 주석 사용 케이스
- 데이터 형
- 리터럴 상수 : 문자 형태로 지정되며 변하지 않음
ex) 'hello world'
- 숫자형
- 정수 - integer
2
- 부동 소수점 - float
52.3E - 4
- 문자열
- 큰따옴표(") 또는 작은 따옴표(')로 지정. 모든 공백 문자나 탭은 그대로 유지.
- 큰따옴표 또는 작은따옴표 출력시 이스케이프(\) 사용.
- r 또는 R을 사용하여 그대로 출력 가능.
- 줄바꿈시 \n 사용.
- \만 사용할 경우 끊김 없이 문자열 정의
- 여러줄의 경우 (""" 또는 )로 표현 가능
"테스트 문자열" -> 테스트 문자열
"테스트 문자열 \"" -> 테스트 문자열 \
r"테스트 문자열 \"" -> 테스트 문자열 \"
"테스트 문자열 \n 다음줄 문자열" ->
테스트 문자열
다음줄 문자열
print ('''테스트 문자열.
다음줄 문자열.
다음줄 문자열.
다음줄 문자열.
''')
- 문자열 포맷팅
- format() 문자열 생성시 다른 정보 포함하여 생성하는 함수
vim place.py
python3 place.py 데이터 사이언스 는 선릉 에서 한다
cat place.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
place = '선릉'
study = '데이터 사이언스'
# 중괄호 안에 숫자는 생략 가능
print ('{0} 는 {1} 에서 한다'.format(study, place))
python3 flt.py 0.333 ___hello___ Swaroop wrote A Byte of Python
cat flt.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# 소수점 이하 셋째 자리까지 부동 소숫점 숫자 표기 (0.333)
print ('{0:.3f}'.format(1.0/3))
# 밑줄(_)ㄹ 11칸을 채우고 가운데 정렬(^)하기 (___hello___)
print ('{0:_^11}'.format('hello'))
# 사용자 지정 키워드 이용해 (Swaproop wrote A Byte of Python) 표기
print ('{name} wrote {book}'.format(name='Swaroop', book='A Byte of Python'))
- 변수
- 변수 : 정보 저장을 위한 컴퓨터의 기억 장치의 한 부분을 가져와 이름을 붙여 사용하는 것
- 변수 식별자 규칙
- 식별자의 첫 문자는 알파벳 문자 (ASCII 대/소문자 혹은 유니코드 문자)이거나 밑줄 (_)이어야 합니다.
- 나머지는 문자 (ASCII 대/소문자 혹은 유니코드 문자), 밑줄(_), 또는 숫자 (0-9)가 될 수 있습니다.
- 식별자는 대/소문자를 구분합니다. 예를 들어, myname과 myName은 다릅니다. 전자의 `n`은 소문자이고,
후자의 `N`은 대문자입니다.
- 올바른 예 i, name_2_3 -잘못된 예 2things, this is spaced out, my-name, >a1b2_c3
- 논리적/물리적 명령행
- 물리적 명령행 : 프로그램 코드 내에서 직접 표현된 한줄
- 논리적 명령행 : 파이썬 인터프리터 관점에서 한 명령 단위
i = 5; print (i) # 세미콜론을 사용하여 하나의 물리적 명령행에 두 개의 논리적 명령행을 사용. 권장하지 않음.
- 들여쓰기
- 명령어 앞에 공백으로 한 명령의 범위를 구분, 이것은 같은 들여쓰기 단계에 있는 명령들은 반드시
같은 들여쓰기를 사용해야 함을 의미합니다.
- 들여쓰기시 파이썬 언어에서 공식적으로 추천하는 방법은 공백 4개.
i = 5
# 다음 행에서 오류가 발생합니다! 행 앞에 잘못된 공백이 한 칸 있습니다.
print ('Value is ', i)
print ('I repeat, the value is '. i)
- 연산자
- 사칙연산 : +,,-,/,*
- 거듭제공: **
- 나머지 : %
- 왼쪽 시프트 : <<
- 지정된 숫자에 대해 비트 수 만큼 왼쪽 시프트 연산
gildangsam@gildangsam-GA-MA74GM-S2H:~$ python3 Python 3.6.6 (default, Sep 12 2018, 18:26:19) [GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux Type "help", "copyright", "credits" or "license" for more information. >>> 2 << 2 8 >>>
2 << 2 # 8을 반환합니다. 2 는 이진수로 10 으로 표현 # 이것을 왼쪽으로 2비트 시프트 연산하면 이진수 1000 이 되고, 이것을 정수로 표현하면 8 이 됨.
- 오른쪽 시프트 : >>
- 지정된 숫자에 대해 지정된 비트 수 만큼 오른쪽 시프트 연산
gildangsam@gildangsam-GA-MA74GM-S2H:~$ python3 Python 3.6.6 (default, Sep 12 2018, 18:26:19) [GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux Type "help", "copyright", "credits" or "license" for more information. >>> 11 >> 1 # # 은 5를 반환. 5 >>> # 11은 이진수로 1011 로 표현됩니다. 이것으로 오른쪽으로 1비트 시프트 연산하면 이진수 101이 되고, 이것을 정수로 표현하면 5가 됨.
- 비트 AND 연산자 : &
5 & 3 # 1을 반환. 5는 이진수로 101. 3은 인진수 011. 각각의 비트를 and로 연산.
- 비트 OR 연산자 : |
5 | 3 # 7을 반환. 5는 이진수로 101. 3은 이진수로 011. 각각의 비트를 or로 연산.
- 비트 XOR 연산자 : ^
5 ^ 3 # 6을 반환. 5는 이진수로 101. 3은 이진수로 011. 각각의 비트를 xor로 연산
- 비트 반전 연산자 : ~
숫자 x의 비트 반전 연산값 -(x+1)을 반환
~5 # -6을 반환
- 비교 연산자 : <,>,<=,>=,==,!=
- 불리언 연산자 : not, and, or
x = true y = false not x = false x and y = false x or y = true
- 흐름제어
- if 문: 조건을 판별하기 위해 사용
num1 = 1
num2 = 2
if num1 == num2:
print('두 숫자는 같다')
else:
print('두 숫자는 다르다')
- while문 : 특정 조건이 참일 경우 블록의 명령문을 반복 실행
- while에도 else사용 가능
num = 1
while num < 10:
print('숫자가 10보다 작음')
num = num + 1
else:
print('숫자가 10보다 크거나 같음')
- for 문 : 열거형을 반복하여 실행할 때 사용.
# range 함수 : 첫번째 숫자 이상, 두번째 숫자 미만의 숫자 목록을 반환
for i in range(1, 5):
print(i)
else:
print('The for loop is over')
- break 문 : 루프문을 강제로 빠져나올 때 사용
num = 1
while num < 10:
if num == 5:
break
print('숫자가 10보다 작음')
else:
print('숫자가 10보다 크거나 같음')
- continue 문 : 현재 실행중인 루프 블록의 나머지 명령문들을 실행하지 않고 곧바로 다음 루프로 넘어갈 때 사용
num = 1
while num < 10:
num = num + 1
if num == 5:
continue
print(num)
- 여기까지입니다. ^^
4주차[편집]
- 날짜 : 11/03
- 참석자 : 4
- 진행한 내용 : matplotlib와 dpandas 문법과 csv를 이용하여 심플한 데이터 분석
- 과제 : 데이터 처리
세부 진행내용[편집]
- python3 matplotlib 그래프 한글 폰트 설정
- python3에서 폰트 설정 없이 한글을 matplotlib 그래프에서 그리면
한글이 깨져서 나옵니다.
- code 내용 (코드 출처 : 파이썬 jupyter notebook 실전 입문 : 터닝포인트)
- code 내용 (코드 출처 : 파이썬 jupyter notebook 실전 입문 : 터닝포인트)
#!/usr/bin/python3
import numpy as np
from matplotlib import pyplot as plt
np.random.seed(0)
x = range(5)
y = 10 + 5 * np.random.randn(5)
flg = plt.figure()
ax = flg.add_subplot(111)
ax.set_title('한글을 지정한 타이틀')
ax.bar(x, y)
plt.show()
- 한글이 깨진 그래프 모습 코드 결과 모습
- 파일:Mat.png
- matplotlib 한글 폰트 설정
- 한글 폰트 설정
- Adobe와 Google이 공동 개발한 한국, 중국, 일본에 사용되고 있는 문자를 이용 가능한 폰트 패밀리
- 한글 폰트 설정
Source Han Sans를 사용하기로 합니다.
- [8] [Source Han Sans 폰트 패밀리가 있는 github 주소]
- 이 github 주소에 있는 특정 폰트를 wget으로 다운로드 받습니다.
wget https://github.com/adobe-fonts/source-han-serif/raw/release/OTF/Korean/SourceHanSerifK-Regular.otf
mv SourceHanSerifK-Regular.otf SourceHanK-Regular.otf
mv SourceHanSerifK-Regular.otf SourceHanK-Regular.otf
mv SourceHanK-Regular.otf SourceHanSansK-Regular.otf
sudo cp SourceHanSansK-Regular.otf /usr/share/fonts/
sudo fc-cache -vf
- 여기까지가 필요한 한글 폰트 우분투 설치준비 과정이었습니다.
- 다음은 우선 특정 디렉토리에 있는 폰트(otf)를 사용하여, 직접 matplotlib
에서 한글 폰트를 이용하는 방법입니다.
#!/usr/bin/python3
import os
import numpy as np
from matplotlib import pyplot as plt, font_manager
font_manager._rebuild()
if os.name == 'nt':
font_dir = font_manager.win32FontDirectory()
else:
font_dir = '/home/gildangsam/sample-data'
font_path = os.path.join(font_dir, 'SourceHanSansK-Regular.otf')
font = font_manager.FontProperties(fname=font_path, size=14)
np.random.seed(0)
x = range(5)
y = 10 + 5 * np.random.randn(5)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('한국어를 지정한 타이틀', fontproperties=font)
ax.set_xlabel('X축', fontproperties=font)
ax.bar(x,y)
plt.show()
- 실행 결과
- 이번 경우는 매번 특정 디렉토리를 지정하는 번거로움에서 벗어난 방법입니다.
#!/usr/bin/python3
# -*- config: utf-8 -*-
import os
import numpy as np
from matplotlib import pyplot as plt, rcParams
# 여기에서 지정된 설정은 초기 설정 값으로 이용된다.
rcParams['font.sans-serif'] = 'Source Han Serif K'
rcParams['font.weight'] = 'regular'
rcParams['axes.titlesize'] = 15
rcParams['ytick.labelsize'] = 12
rcParams['xtick.labelsize'] = 12
np.random.seed(0)
x = range(5)
y = 10 + 5 * np.random.randn(5)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('한국어를 지정한 타이틀')
ax.set_xlabel('X축')
ax.bar(x,y)
plt.show()
- 실행결과 : rcParams를 이용한 폰트 지정 방법
- 다음은 matplotlib의 설정 파일인 matplotlibrc 파일을 현재 디렉토리에
복사하는 방법입니다.
#!/usr/bin/python3 #-*- coding: utf-8 -*- import shutil from matplotlib import matplotlib_fname shutil.copyfile(matplotlib_fname(), 'matplotlibrc')
- 이 복사된 matplotlibrc 설정파일을 열어서 다음과 같이 저장하면, 다음번에는
굳이 rcParams를 사용하지 않아도 됩니다.
205 font.serif : Source Han Serif K, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
- 복사된 matplotlibrc 설정파일을 열어서 205행에 있는 주석 표시를 해제하고, Source Han Serif K 라고
명시합니다.
- 저장하고 나옵니다.
#!/usr/bin/python3
# -*- config: utf-8 -*-
import os
import numpy as np
from matplotlib import pyplot as plt
# 여기에서 지정된 설정은 초기 설정 값으로 이용된다.
#rcParams['font.sans-serif'] = 'Source Han Sans K'
#rcParams['font.weight'] = 'regular'
#rcParams['axes.titlesize'] = 15
#rcParams['ytick.labelsize'] = 12
#rcParams['xtick.labelsize'] = 12
np.random.seed(0)
x = range(5)
y = 10 + 5 * np.random.randn(5)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('한국어를 지정한 타이틀')
ax.set_xlabel('X축')
ax.bar(x,y)
plt.show()
- 같은 결과가 나오므로 이미지는 생략합니다.
- 여기까지가 한글 설정 내용이었으며, 다음은 jupyter notebook에서
실제 스터디 모임에서 사용된 데이터를 ipynb 파일에서 py로 변환하여 코드를 적습니다.
# coding: utf-8
# In[1]:
import os
# In[2]:
base_url = 'https://raw.githubusercontent.com/practical-jupyter/sample-data/master/anime/'
anime_csv = os.path.join(base_url, 'anime.csv')
# In[3]:
print(anime_csv)
# In[4]:
import pandas as pd
jupyter nbconvert --to script
# In[5]:
anime_csv = os.path.join(base_url, 'anime.csv')
pd.read_csv(anime_csv).head()
# In[6]:
anime_master_csv = os.path.join(base_url, 'anime_master.csv')
pd.read_csv(anime_master_csv).head()
# In[7]:
anime_split_genre_csv = os.path.join(base_url, 'anime_split_genre.csv')
pd.read_csv(anime_split_genre_csv).head()
jupyter nbconvert --to script
# In[8]:
anime_genre_top10_csv = os.path.join(base_url, 'anime_genre_top10.csv')
pd.read_csv(anime_genre_top10_csv).head()
# In[9]:
anime_genre_top10_pivoted_csv = os.path.join(base_url, 'anime_genre_top10_pivoted.csv')
pd.read_csv(anime_genre_top10_pivoted_csv).head()
# In[12]:
anime_stock_price_csv = os.path.join(base_url, 'anime_stock_price.csv')
pd.read_csv(anime_stock_price_csv, index_col =0, parse_dates=['Date']).head()
# In[13]:
anime_stock_returns_csv = os.path.join(base_url, 'anime_stock_returns.csv')
pd.read_csv(anime_stock_returns_csv, index_col=0, parse_dates=['Date']).head()
# In[15]:
t4816_csv = os.path.join(base_url, '4816.csv')
pd.read_csv(t4816_csv, index_col=0, parse_dates=['Date']).head()
# Series 작성
# =============
# In[16]:
import pandas as pd
ser = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
ser
# index를 생략한 Series 작성
# -------------
# In[21]:
import pandas as pd
pd.Series([1, 2, 3])
# 레이블을 사용해서 데이터를 선택하기
# -------------
# In[22]:
ser.loc['b']
# In[23]:
ser['b']
# In[24]:
ser.loc['b':'c']
# 복수의 요소 지정
# -------------
# In[25]:
ser.loc[['a', 'c']]
# In[26]:
ser.iloc[1]
# In[27]:
ser.iloc[1:3]jupyter nbconvert --to script
# 논리값을 사용해서 데이터 선택하기
# -------------
# In[28]:
ser.loc[[True, False, True]]
# In[29]:
ser != 2
# In[30]:
ser.loc[ser != 2]
# DataFrame
# =============
# DataFrame 작성하기
# -------------
# In[32]:
import pandas as pd
df = pd.DataFrame(
[[1, 10, 100], [2, 20, 200], [3, 30, 300]],
index=['r1', 'r2', 'r3'],
columns=['c1', 'c2', 'c3']
)
df
# 레이블을 사용해서 데이터 선택하기
# -------------
# In[33]:
df.loc['r2', 'c2']
# 모든 행(열)을 지정하는 경우
# -------------
# In[34]:
df.loc['r2', :]
# 모든 행에 레이블 지정
# -------------
# In[35]:
df.loc[:, 'c2']
# In[37]:
df.loc[['r1', 'r3'], 'c2' : 'c3']
# iloc를 사용해서 데이터를 선택하기
# -------------
# In[38]:
df.iloc[1:3, [0, 2]]
# 열 이름을 지정해서 데이터 선택하기
# -------------
# In[39]:
df['c2']
# 논리값을 사용해서 데이터 선택하기
# -------------
# In[40]:
df > 10
# In[42]:
df.loc[df['c2'] > 10]
# In[44]:
df.loc[(df['c1'] > 1) & (df['c3'] < 300)]
# CSV 파일 불러오기
# -------------
# In[46]:
import os
import pandas as pd
base_url = 'https://raw.githubusercontent.com/practical-jupyter/sample-data/master/anime/'
anime_csv = os.path.join(base_url, 'anime.csv')
df = pd.read_csv(anime_csv)
df.head()
# In[48]:
df = pd.read_csv(anime_csv, index_col=0)
df.head()
# In[50]:
df = pd.read_csv(anime_csv, index_col ='anime_id')
df.head()
# In[53]:
df = pd.read_csv(anime_csv, dtype={'memebers' : float})
df.head()
# In[54]:
anime_stock_price_csv = os.path.join(base_url, 'anime_stock_price.csv')
df = pd.read_csv(anime_stock_price_csv, parse_dates=['Date'])
df.dtypes
# In[55]:
anime_tsv = os.path.join(base_url, 'anime.tsv')
df = pd.read_csv(anime_tsv, sep='\t')
# In[56]:
df.head()
# In[57]:
df.dtypes
5주차[편집]
- 날짜 : 11/10
- 참석자 : 2
- 진행한 내용 : pandas 기본
- 과제 : 데이터 분석 시각화
세부 진행내용[편집]
- pandas 기초
- pandas는?
- pandas는 파이썬에서 사용하는 데이터 분석 라이브러리로, 행과 열로 이루어진 데이터 객체를
- pandas는?
만들어 다룰 있게 되며 보다 안정적으로 대용량의 데이터들을 처리하는 데 매우 용이합니다.
- pandas 사용하기
import numpy as np import pandas as pd
- pandas 자료구조
- pandas에서는 기본적으로 정의되는 자료구조인 Series와 Data Frame을 사용합니다.
- pandas 자료구조
이 자료구조들은 빅 데이터 분석에 있어서 높은 수준의 성능을 퍼포먼스를 발휘합니다. 그럼 series에 대해서 알아보기로 합니다.
- sereis 정의하기
#series 정의하기 gildang = pd.Series([4, 7, -5, 3]) gildang
0 4 1 7 2 -5 3 3 dtype: int64
# series의 값만 확인하기 gildang.values
array([ 4, 7, -5, 3])
# series의 인덱스만 확인하기 gildang.dtypes
dtype('int64')
#인덱스를 바꿀 수 있습니다. gildang2 = pd.Series([4, 7, -5, 3], index=['d','b','a','c']) gildang2
d 4 b 7 a -5 c 3 dtype: int64
# python의 dictionary 자료형을 series data로 만들 수 있습니다.
# dictionary 의 key가 series의 index 가 됩니다.
gildata = {'Kim': 35000, 'Bumsun': 67000, 'Joe': 12000, 'Hong': 4000}
gildang3 = pd.Series(gildata)
gildang3
Kim 35000 Bumsun 67000 Joe 12000 Hong 4000 dtype: int64
gildang3.name = 'Tomson' gildang3.index.name = 'Names' gildang3
Names Kim 35000 Bumsun 67000 Joe 12000 Hong 4000 Name: Tomson, dtype: int64
# index 변경 gildang3.index = ['A', 'B', 'C', 'D'] gildang3
A 35000 B 67000 C 12000 D 4000 Name: Tomson, dtype: int64
# Data Frame 정의하기
# 이전에 data frame에 들어갈 데이터를 정의해야 하는데,
# 이는 python의 dictioanry 또는 numpy 의 array로 정의할 수 있습니다.
data = {'name' : ['Bumsun', 'Bumsun', 'Bumsun', 'Kim', 'Park'],
'year' : [2013, 2014, 2015, 2016, 2015],
'points' : [1.5, 1.7, 3.6, 2.4, 2.9]}
df = pd.DataFrame(data)
df
name year points 0 Bumsun 2013 1.5 1 Bumsun 2014 1.7 2 Bumsun 2015 3.6 3 Kim 2016 2.4 4 Park 2015 2.9
# 행과 열의 구조를 가진 데이터가 생깁니다.
# 행 방향의 index df.index
RangeIndex(start=0, stop=5, step=1)
# 열 방향의 index df.columns
Index(['name', 'year', 'points'], dtype='object')
# 값 얻기 df.values
array([['Bumsun', 2013, 1.5],
['Bumsun', 2014, 1.7],
['Bumsun', 2015, 3.6],
['Kim', 2016, 2.4],
['Park', 2015, 2.9]], dtype=object)
# 각 인덱스에 대한 이름 설정하기 df.index.name = 'Num' df.columns.name = 'Info' df
nfo name year points Num 0 Bumsun 2013 1.5 1 Bumsun 2014 1.7 2 Bumsun 2015 3.6 3 Kim 2016 2.4 4 Park 2015 2.9
# dataframe을 만들면서 columns와 index를 섲정할 수 있습니다.
df2 = pd.DataFrame(data, columns=['year', 'name', 'points', 'penalty'],
index=['one', 'two', 'three', 'four', 'five'])
df2
year name points penalty one 2013 Bumsun 1.5 NaN two 2014 Bumsun 1.7 NaN three 2015 Bumsun 3.6 NaN four 2016 Kim 2.4 NaN five 2015 Park 2.9 NaN
- DataFrame을 정의하면서, data로 들어가는 python dictionary의 columns의 순서가 달라도 알아서 맞춰서
정의됩니다.
하지만 data에 포함되어 있지 않은 값은 NaN(Non a Number)으로 나타나게 되는데, 이는 null과 같은 개념입니다. null 값은 춯에 어더한 방법으로도 처리가 되지 않는 데이터입니다. 따라서 올바른 데이터 처리를 위해 추가적으로 값을 넣어 주어야 합니다.
# describe() 함수는 DataFrame의 계산 가능한 값드레 대한 다양한 계산 값을 보여줍니다. df2.describe()
year points count 5.000000 5.000000 mean 2014.600000 2.420000 std 1.140175 0.864292 min 2013.000000 1.500000 25% 2014.000000 1.700000 50% 2015.000000 2.400000 75% 2015.000000 2.900000 max 2016.000000 3.600000
- DataFrame Indexing
data = {'names' : ['gilhan', 'gilhan', 'gilhan', 'Susan', 'Jane'],
'year' : [2014, 2015, 2016, 2015, 2016],
'points' : [1.5, 1.7, 3.6, 2.4, 2.9]}
df = pd.DataFrame(data, columns=['year', 'names', 'points', 'penalty'],
index=['one', 'two', 'three', 'four', 'five'])
df
year names points penalty one 2014 gilhan 1.5 NaN two 2015 gilhan 1.7 NaN three 2016 gilhan 3.6 NaN four 2015 Susan 2.4 NaN five 2016 Jane 2.9 NaN
- Dataframe에서 열을 선택해서 조작하기
df['year']
one 2014 two 2015 three 2016 four 2015 five 2016 Name: year, dtype: int64
# 동일한 의미를 갖는 다른 방법 df.year
one 2014 two 2015 three 2016 four 2015 five 2016 Name: year, dtype: int64
df[['year', 'points']]
year points one 2014 1.5 two 2015 1.7 three 2016 3.6 four 2015 2.4 five 2016 2.9
# 특정 열에 대해 위와 같이 선택하고, 원하는 값을 대입할 수 있습니다. df['penalty'] = 0.5
df
year names points penalty one 2014 gilhan 1.5 0.5 two 2015 gilhan 1.7 0.5 three 2016 gilhan 3.6 0.5 four 2015 Susan 2.4 0.5 five 2016 Jane 2.9 0.5
# 또는 df['penalty'] = [0.1, 0.2, 0.3, 0.4, 0.5] df
year names points penalty one 2014 gilhan 1.5 0.1 two 2015 gilhan 1.7 0.2 three 2016 gilhan 3.6 0.3 four 2015 Susan 2.4 0.4 five 2016 Jane 2.9 0.5
# 새로운 열을 추가 df['zeros'] = np.arange(5) df
year names points penalty zeros one 2014 gilhan 1.5 0.1 0 two 2015 gilhan 1.7 0.2 1 three 2016 gilhan 3.6 0.3 2 four 2015 Susan 2.4 0.4 3 five 2016 Jane 2.9 0.5 4
# Series도 추가할 수 있습니다. val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
df['debt'] = val df
year names points penalty zeros debt one 2014 gilhan 1.5 0.1 0 NaN two 2015 gilhan 1.7 0.2 1 -1.2 three 2016 gilhan 3.6 0.3 2 NaN four 2015 Susan 2.4 0.4 3 -1.5 five 2016 Jane 2.9 0.5 4 -1.7
- 하지만 Series로 넣을 때는 val과 같이 넣으려는 data의 index에 맞춰서 데이터가 들어갑니다.
이점이 python list나 numpy array로 데이터를 넣을때와 가탕 큰 차이점입니다.
df['net_points'] = df['points'] - df['penalty']
df['high_points'] = df['net_points'] > 2.0
df
year names points penalty zeros debt net_points high_points one 2014 gilhan 1.5 0.1 0 NaN 1.4 False two 2015 gilhan 1.7 0.2 1 -1.2 1.5 False three 2016 gilhan 3.6 0.3 2 NaN 3.3 True four 2015 Susan 2.4 0.4 3 -1.5 2.0 False five 2016 Jane 2.9 0.5 4 -1.7 2.4 True
# 열 삭제 del df['high_points']
del df['net_points'] del df['zeros']
df
year names points penalty debt one 2014 gilhan 1.5 0.1 NaN two 2015 gilhan 1.7 0.2 -1.2 three 2016 gilhan 3.6 0.3 NaN four 2015 Susan 2.4 0.4 -1.5 five 2016 Jane 2.9 0.5 -1.7
df.columns
Index(['year', 'names', 'points', 'penalty', 'debt'], dtype='object')
df.index.name = 'Order' df.columns.name = 'Info'
df
Info year names points penalty debt Order one 2014 gilhan 1.5 0.1 NaN two 2015 gilhan 1.7 0.2 -1.2 three 2016 gilhan 3.6 0.3 NaN four 2015 Susan 2.4 0.4 -1.5 five 2016 Jane 2.9 0.5 -1.7
- DataFrame에서 행을 선택하고 조작하기
- pandas에서는 Dataframe에서 행을 인덱싱하는 방법이 많습니다.
- DataFrame에서 행을 선택하고 조작하기
# 0번째 부터 2(3-1) 번째까지 가져옵니다. # 뒤에 써준 숫자번째의 합을 뺍니다. df[0:3]
Info year names points penalty debt Order one 2014 gilhan 1.5 0.1 NaN two 2015 gilhan 1.7 0.2 -1.2 three 2016 gilhan 3.6 0.3 NaN
# two라는 행부터 four라는 행까지 가져옵니다. # 뒤에 써준 이름의 행을 빼지 않습니다. df['two':'four'] # 이것은 비추천!
# 아래 방법을 권장합니다. # .loc 또는 .iloc 함수를 사용하는 방법입니다. df.loc['two'] # 반환 형태는 Series
Info year 2015 names gilhan points 1.7 penalty 0.2 debt -1.2 Name: two, dtype: object
df.loc['two' : 'four']
Info year names points penalty debt Order two 2015 gilhan 1.7 0.2 -1.2 three 2016 gilhan 3.6 0.3 NaN four 2015 Susan 2.4 0.4 -1.5
df.loc['two' : 'four', 'points']
Order two 1.7 three 3.6 four 2.4 Name: points, dtype: float64
df.loc[:, 'year'] # ==df['year']
Order one 2014 two 2015 three 2016 four 2015 five 2016 Name: year, dtype: int64
df.loc[:,['year', 'names']]
Info year names Order one 2014 gilhan two 2015 gilhan three 2016 gilhan four 2015 Susan five 2016 Jane
df.loc['three':'five', 'year':'penalty']
Info year names points penalty Order three 2016 gilhan 3.6 0.3 four 2015 Susan 2.4 0.4 five 2016 Jane 2.9 0.5
# 새로운 행 넣기 df.loc['six',:] = [2013,'Jun',4.0,0.1,2.1] df
Info year names points penalty debt Order one 2014.0 gilhan 1.5 0.1 NaN two 2015.0 gilhan 1.7 0.2 -1.2 three 2016.0 gilhan 3.6 0.3 NaN four 2015.0 Susan 2.4 0.4 -1.5 five 2016.0 Jane 2.9 0.5 -1.7 six 2013.0 Jun 4.0 0.1 2.1
# iloc 사용 : index 번호를 사용합니다. df.iloc[3] # 3번째 행을 가져옵니다.
Info year 2015 names Susan points 2.4 penalty 0.4 debt -1.5 Name: four, dtype: object
df.iloc[3:5, 0:2]
Info year names Order four 2015.0 Susan five 2016.0 Jane
df.iloc[[0,1,3], [1,2]]
Info names points Order one gilhan 1.5 two gilhan 1.7 four Susan 2.4
df.iloc[:,1:4]
Info names points penalty Order one gilhan 1.5 0.1 two gilhan 1.7 0.2 three gilhan 3.6 0.3 four Susan 2.4 0.4 five Jane 2.9 0.5 six Jun 4.0 0.1
- Dataframe에서의 boolean indexing
df
Info year names points penalty debt Order one 2014.0 gilhan 1.5 0.1 NaN two 2015.0 gilhan 1.7 0.2 -1.2 three 2016.0 gilhan 3.6 0.3 NaN four 2015.0 Susan 2.4 0.4 -1.5 five 2016.0 Jane 2.9 0.5 -1.7 six 2013.0 Jun 4.0 0.1 2.1
# year가 2014보다 큰 boolean data df['year'] > 2014
Order one False two True three True four True five True six False Name: year, dtype: bool
# year가 2014보다 큰 모든 행의 값 df.loc[df['year']>2014,:]
Info year names points penalty debt Order two 2015.0 gilhan 1.7 0.2 -1.2 three 2016.0 gilhan 3.6 0.3 NaN four 2015.0 Susan 2.4 0.4 -1.5 five 2016.0 Jane 2.9 0.5 -1.7
df.loc[df['names'] == 'gilhan',['names','points']]
Info names points Order one gilhan 1.5 two gilhan 1.7 three gilhan 3.6
# numpy에서와 같이 논리연산을 응용할 수 있습니다. df.loc[(df['points']>2)&(df['points']<3),:]
Info year names points penalty debt Order four 2015.0 Susan 2.4 0.4 -1.5 five 2016.0 Jane 2.9 0.5 -1.7
# 새로운 값을 대입할 수 있습니다. df.loc[df['points'] > 3, 'penalty'] = 0 df
Info year names points penalty debt Order one 2014.0 gilhan 1.5 0.1 NaN two 2015.0 gilhan 1.7 0.2 -1.2 three 2016.0 gilhan 3.6 0.0 NaN four 2015.0 Susan 2.4 0.4 -1.5 five 2016.0 Jane 2.9 0.5 -1.7 six 2013.0 Jun 4.0 0.0 2.1
#data #dataframe을 만들 때 index, column을 설정하지 않으면 기본값으로 0부터 시작하는 정수형 숫자로 입력됩니다. df = pd.DataFrame(np.random.randn(6,4)) df
0 1 2 3 0 -0.835186 1.165282 1.831968 0.173191 1 -0.997786 -1.576526 0.328593 0.563764 2 1.281101 0.267556 0.238319 -0.752243 3 -1.262262 0.557999 -0.174194 0.445374 4 -0.636935 -0.386043 1.011462 -0.419366 5 0.288283 0.272665 0.520356 -0.660329
df.colums = ['A', 'B', 'C', 'D']
df.index = pd.date_range('20160701', periods=6)
# pandas에서 제공하는 date rang 함수는 datetime 자료형으로 구성된, 날자 시각 등을 알 수 있는 자료형을 만드는 함수입니다.
df.index
DatetimeIndex(['2016-07-01', '2016-07-02', '2016-07-03', '2016-07-04',
'2016-07-05', '2016-07-06'],
dtype='datetime64[ns]', freq='D')
df
0 1 2 3 2016-07-01 -0.835186 1.165282 1.831968 0.173191 2016-07-02 -0.997786 -1.576526 0.328593 0.563764 2016-07-03 1.281101 0.267556 0.238319 -0.752243 2016-07-04 -1.262262 0.557999 -0.174194 0.445374 2016-07-05 -0.636935 -0.386043 1.011462 -0.419366 2016-07-06 0.288283 0.272665 0.520356 -0.660329
#np.nan은 NaN 값을 의미합니다. df['F'] = [1.0, np.nan, 3.5, 6.1, np.nan, 7.0] df
0 1 2 3 F 2016-07-01 -0.835186 1.165282 1.831968 0.173191 1.0 2016-07-02 -0.997786 -1.576526 0.328593 0.563764 NaN 2016-07-03 1.281101 0.267556 0.238319 -0.752243 3.5 2016-07-04 -1.262262 0.557999 -0.174194 0.445374 6.1 2016-07-05 -0.636935 -0.386043 1.011462 -0.419366 NaN 2016-07-06 0.288283 0.272665 0.520356 -0.660329 7.0
#Nan 없애기 # 행의 값 중 하나라도 nan인 경우 그 행을 없앱니다. df.dropna(how='any')
0 1 2 3 F 2016-07-01 -0.835186 1.165282 1.831968 0.173191 1.0 2016-07-03 1.281101 0.267556 0.238319 -0.752243 3.5 2016-07-04 -1.262262 0.557999 -0.174194 0.445374 6.1 2016-07-06 0.288283 0.272665 0.520356 -0.660329 7.0
# 행의 모든 값이 nan인 경우 그 행을 없앱니다. df.dropna(how='all')
0 1 2 3 F 2016-07-01 -0.835186 1.165282 1.831968 0.173191 1.0 2016-07-02 -0.997786 -1.576526 0.328593 0.563764 NaN 2016-07-03 1.281101 0.267556 0.238319 -0.752243 3.5 2016-07-04 -1.262262 0.557999 -0.174194 0.445374 6.1 2016-07-05 -0.636935 -0.386043 1.011462 -0.419366 NaN 2016-07-06 0.288283 0.272665 0.520356 -0.660329 7.0
# nan에 값을 넣기 df.fillna(value=0.5)
0 1 2 3 F 2016-07-01 -0.835186 1.165282 1.831968 0.173191 1.0 2016-07-02 -0.997786 -1.576526 0.328593 0.563764 0.5 2016-07-03 1.281101 0.267556 0.238319 -0.752243 3.5 2016-07-04 -1.262262 0.557999 -0.174194 0.445374 6.1 2016-07-05 -0.636935 -0.386043 1.011462 -0.419366 0.5 2016-07-06 0.288283 0.272665 0.520356 -0.660329 7.0
# nan값인지 확인하기 df.isnull()
0 1 2 3 F 2016-07-01 False False False False False 2016-07-02 False False False False True 2016-07-03 False False False False False 2016-07-04 False False False False False 2016-07-05 False False False False True 2016-07-06 False False False False False
# F열에서 nan값을 포함하는 행만 추출하기 df.loc[df.isnull()['F'],:]
0 1 2 3 F 2016-07-02 -0.997786 -1.576526 0.328593 0.563764 NaN 2016-07-05 -0.636935 -0.386043 1.011462 -0.419366 NaN
pd.to_datetime('20160701')
</pre.
<pre>
Timestamp('2016-07-01 00:00:00')
#이상 여기까지만 줄입니다.
참고는 여기서하였습니다. https://doorbw.tistory.com/172
6주차[편집]
- 날짜 : 11/17
- 참석자 :
- 진행한 내용 :
- 과제 :
7주차[편집]
- 날짜 : 11/24
- 참석자 :
- 진행한 내용 :
- 과제 :
8주차[편집]
- 날짜 : 12/01
- 참석자 :
- 진행한 내용 :
- 과제 :
후원[편집]
1. KOSSLAB(장소)
참고[편집]
- 내용을 추가해주시는 건 18년 대전 ARM Study 문서를 참고해주세요