18년 서울 Data Science 스터디

깊이있는 삽질 Ubuntu Korea Community Wiki
이동: 둘러보기, 검색

개요[편집]

  • 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"을 눌러주세요.
print("Hello, World!")
    • Py4.png
  • 실습 - 라이브러리를 활용하여 그래프(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()
  • Py5.png


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 실전 입문 : 터닝포인트)
#!/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()
      • 실행 결과

Mat2.png

      • 이번 경우는 매번 특정 디렉토리를 지정하는 번거로움에서 벗어난 방법입니다.
#!/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를 이용한 폰트 지정 방법

Mat3.png

      • 다음은 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 사용하기
import numpy as np
import pandas as pd
    • pandas 자료구조
      • pandas에서는 기본적으로 정의되는 자료구조인 Series와 Data Frame을 사용합니다.

이 자료구조들은 빅 데이터 분석에 있어서 높은 수준의 성능을 퍼포먼스를 발휘합니다. 그럼 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' </pre>

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에서 행을 인덱싱하는 방법이 많습니다.
# 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(장소)


참고[편집]