빅데이터 관련 프로그래밍

각종 주의점들

  1. 필드는 오로지 1줄에 다 입력시키고, 많아지면 데이터 > 그룹을 활용하자
    • 칼럼1, 칼럼2, ..., 칼럼n, 빈 칼럼에서, 빈칼럼 앞까지 그룹을 해주면 빈 칼럼이 그룹명이 된다.





  1. 필드명은 영어로 하자. 통계 프로그램에서 인식 못할 수 도 있다.
    • 대쉬(-)보다는 언더바(_)가 좋다
  1. 범주 2개형의 경우, 성별이나 기저질환 유무 등 하나를 명시하고 다른하나는 0으로 나타내자. 그리고 데이터 유효성 검사를 활용하여, 각 셀에 입력될 값을 제한시키자.

    • 나이의 경우, 정수여야하며, 연령대 제한은 범위로 할 수 있다.







  • 성별(MALE)의 경우, 목록의 형태로 0,1만 오도록 제한할 수 있으며, 반드시 콤마로 나누어주어야한다. 그러면 드랍다운이 생기면서 선택하거나, 직접 0or1을 입력할 수 있다.




블로그정리 1. np.random모듈

numpy 의 np.random. randint vs rand/randn

np.random.seed seed를 통한 난수 생성

np.random.randint 균일 분포의 정수 난수 1개 생성
np.random.rand 0부터 1사이의 균일 분포에서 난수 matrix array생성
np.random.randn 가우시안 표준 정규 분포에서 난수 matrix array생성

np.random.shuffle 기존의 데이터의 순서 바꾸기
np.random.choice 기존의 데이터에서 sampling
np.unique 데이터에서 중복된 값을 제거하고 중복되지 않는 값의 리스트를 출력
np.bincount 발생하지 않은 사건에 대해서도 카운트를 해준다

In [1]:
import numpy as np

random.randint 와 np.random.randint : 모두 (시작, n-1) 사이의 랜덤숫자 1개 뽑아내기

In [3]:
np.random.randint(6) # 0 or 1 or ~ or 5      0부터 5까지 랜덤한 숫자 1개 
Out[3]:
5
In [4]:
np.random.randint(1, 20) # 1부터 19까지 랜덤숫자 1개
Out[4]:
19

np.random.rand(m,n) : 0 ~ 1의 균일분포 표준정규분포 난수를 matrix array(m,n) 생성

In [5]:
np.random.rand(6)  
Out[5]:
array([0.82374834, 0.03504426, 0.19848749, 0.47607174, 0.98983665,
       0.63021609])
In [6]:
np.random.rand(3,2)
Out[6]:
array([[0.21023055, 0.46075628],
       [0.99993567, 0.29630209],
       [0.79509783, 0.05405658]])

np.random.randn(m,n) : 평균0, 표준편차1의 가우시안 표준정규분포 난수를 matrix array(m,n) 생성

In [7]:
np.random.randn(6)
Out[7]:
array([ 0.42240858,  0.39214236, -0.05216362, -0.31037385, -1.75930161,
        0.04749234])
In [8]:
np.random.randn(3, 2)
Out[8]:
array([[ 1.65238965, -0.75137173],
       [-1.59079976, -1.26309433],
       [ 0.20991563,  2.23786713]])

list, set comprehension 정리

2019. 1. 30. 21:33

리스트 속 요소들을 변환한 리스트를 반환받는 법

  1. 변환될 빈 리스트 생성 -> for문 돌면서 처리 -> 각각 append
  2. list comprehension
  3. list ( map ( lambda x: , list ) )

리스트 속 요소들을 필터링한 리스트 반환받는 법

  1. list comprehenshion + if
    1) [ x if 조건1 else 조건 2 for in ]
    2) [ x for in if 조건1 ]
  2. list ( filter(lambda x: , list ) )

리스트 vs set

  1. list() :  [1, 2, 3] or []  로 생성하면 append한다
  2. set() :  {1, 2, 3} 로 생성하면 add한다.
  3. { } 로 생성은 빈 딕셔너리다 ! set이 아니다! set의 양쪽 구성만 { }

리스트 속 요소들을 변환한 set을 반환받는 방법

  1. { set comprehension for in 리스트 }


R 마크다운 팁 + 단축키

2019. 1. 30. 09:22
  1. html로 Knit 할 때 옵션이 항상 헤깔렸는데 Chunk Output in Console을 선택해야지, 현재 Rmd에 결과안뜨지만 Knit시 결과가 잘나오는 것을 확인

  2. chunk 생성 : Ctrl + Alt + I

  3. knit 단축키 : Ctrl + Shift + K

  4. 주석 : ctrl+shift+/ (내가 설정함)

  5. 구역나누기 주석 : Ctrl + shift + R


A : 현재 셀의 위에 새로운 셀을 추가한다.
B : 현재 셀 밑에 새로운 셀을 추가한다.
M : 현재 셀을 markdown 모드로 변경한다.
Y : markdown 모드를 다시 code 모드로 변경한다.
D+D : 현재 셀을 삭제한다.
Enter : command 모드에서 edit 모드로 변경한다.
F : 코드를 find and replace 한다.
O : Output 접기
Shift + Tab : 객체의 docstring(documentation)을 출력한다
Shift + M : 을 누르면 선택된 셀들을 merge 한다.

참고 : https://3months.tistory.com/115?category=753896

파일명 : watch_court.py
필요파일 : 크롬드라이버.exe


나만의 beautifulsuop 객체에 대한 정의

  • ?.태그명 : 해당 태그 하위 전체구조들까지 다 가져오기    ex> soup.body

  • 태그명.find_all( '태그명' ) : 하위의 모든 태그 중 여러개의 특정 태그를 리스트로 가져오기    ex> .find_all('tr')
  • 태그명.find( 속성 = '특정 속성명' ) : 하위의 모든 태그 중  특정 속성으로 검색    ex> .find(id = 'ea_list')

  • 태그명.get('속성') : 해당 태그안의 속성의 내용물을 가져옴   ex> a.get('href')



19.에서 했던 web_scrapping_example.py에 대해서,, 게시판 링크를 타고 추가 정보도 가져와야할 상황이다.
즉, 게시판을 클릭에서 그 글속에 정보도 가져와야한다.
image
image

  • 먼저, 1 ~ 100page까지 스크래핑했던 for문을 range(1, 2)까지로 줄이자. ( 다 완성된 뒤 100으로 수정하자)
    - # TODO 를 활용하였다.
    image


  • 게시판의 각 줄을 의미하는 line안의  각 칸<td> 중 게시글 제목칸인 td_list[1]를 보자.
    .text제외시키고  제목칸 <td>태그 안에는 링크 주소태그 <a> 태그가 있다.
    image


  • *** my) 만약, 이것을 bs4로 scrapping으로 처리한다면, 클릭해서 게시판으로 들어가는 시간 등을 처리 못하게 된다.
    *** 또한, href주소를 main url 뒤에 붙혀넣은 뒤, 홈페이지의 주소가 다르게 바뀌는 것 또한 문제를 발생시킨다
    그래도 한다고 가정하고 시행해보면,
    1. td 태그의 a태그로 이동 : td.a
      image
    2. a 태그의 href 속성의 내용물 가져오기 : a.get('href)
      - ***여기서 /뒤의 주소는 원래 웹사이트의 메인url인 http://watch.peoplepower21.org 뒤에 달리는 것이다.
      image
      image

      *** 하지만, 홈페이지가 로딩이 완료되면 주소가 변해있다.
      *** 이로 인해 문제가 발생할 것이다.

      image

    3. 이제 main url + href의 문자열을 합한 url을 requests.get() -> response.text -> html-> soup -> body 로 접근할 수 있다.
      *** 하지만, 데이터 로딩중이라는 문구와 함께 body치고는 너무 짧은 태그들만 보인다.
      *** 그 이유는 href를 이용한 url은 로딩을 준비하는 페이지로 가기 때문이다.

      image
      image


    4. 이럴 때 사용하는 것이 selenium이다.


selenium의 webdriver & chromedriver 설치

  1. 설치
    image

  2. from selenium import webdriver
    image

  3. 웹드라이버 중 크롬드라이버 이용을 위한 browser객체 만들기
    *** 첫 실행시 오류가 뜬다. 에러 중 마지막 줄 사이트로 이동해서 크롬드라이버 최신버전을 설치하자.
    image


  4. 크롬드라이버 설치
    https://sites.google.com/a/chromium.org/chromedriver/home

    image
    image
    image

    압축푼 파일을 해당 파이참 프로젝트 안에 붙혀넣기하자.
    imageimage
    image

  5. 다시 한번 크롬드라이버 객체browser를 생성하는 것을 실행시켜보자.
    - 크롬창이 하나 뜨면서 자동화된 테스트 소프트웨어에 의해 제어되고 있다고 뜬다.
    - 크롤링이 다 끊나고 browser도 꺼져야 하므로, py파일 맨 마지막에 browser.quit를 생성과 동시에 적어주는 버릇을 들이자.
    image

    image




selenium - webdriver - chromedriver를 이용해서 연결페이지를 가서 추가정보 가져오기

  1. 앞에서 시도 했던 부분 중  게시글td태그안의 a태그 -> href내용물 가져오기의 코드만 살려놓는다.
    - sele - web- chromedriver로 페이지를 타고 갈 때는, requests.get( url )부분을 대체하여 사용하는 것이다.
    - url을 얻은 상태에서 browser.get( url )시작한다.
    - 현재 상태로 실행하면, 작업은 없지만 연결된 페이지가 로딩이 완료되고, 다음 loop로 가는 것을 확인할 수 있다.
    - 그 이후에는

    image
    image


    image
    image
    image


  2. browser.get(url)로 받은 반응은    response = requests.get(url) 에 대응되고
    변수없이 browser객체에 할당된 반응은
    html = broswer.page_source 를 통해 html을 받아와야한다. 이것은 html = response.text에 대응된다.
    image



  3. html을 받았으면, 이전과정과 똑같이, beautifulsoup을 통해 스크래핑 하면 되는 것이다.
    image


  4. body 이후에서는 무엇을 가져와야할지(이전에는 게시판 첫 글을 검색) ctrl + u 를 통해 필요한 내용물의 자리를 살펴보자.
    - 우리는 해당 페이지에서 발의자라고 써있는 부분을 찾아보자.
    image
    image

  5. 우리가 필요한 발의자들 목록의 상위에서 많은 <div>태그들 가운데 id를 가지고 있는 <div>태그가 보인다.
    id는 한 페이지당 고유값이므로 body에서 .find(id = )로 한방에 타고들어간다.
    또한, 해당id <div>태그만 찾으면, 안에 text내용물은 발의자 목록 밖에 안보이므로, 쉽게 내용물을 가져올 수 있을 것 같다.
    image
    image

    하지만, 내용물이 제대로 안보인다.
    .text는 하위태그의 텍스트를 다 가져오긴 하지만,
    단지, selenium-webdriver-chromedriver가 페이지로딩이 완료가 다되고, 다음loop를 도는 기능은 있으나,
    selenium이  최종 페이지를 로딩하자마자, 바로 다음 loop로 넘어가는 식으로 수행하기 때문에
    bs4가 스크래핑할 시간이 없게 된다.
    image


  6. 이 때, 사용하는 것이 크롬드라이버의 객체 broswer를 이용한 암묵적인 기다림을 의미하는 .implicitly_wait( )이다.
    필요한 html코드를 페이지에서 받아오기 전, 5초를 기다려준다고 해봤다.
    하지만, 로딩되자마자 떠나는 것이 문제이므로 이것은 해결책이 안된다.
    image


Selenium의  WebDriverWait() + EC + By클래스를 이용하여 특정속성의 출현 확실히 기다려주기

  1. selenium이 로딩되자마자 떠나는 것을 방지하기 위해,
    해당id태그가 확!실!히! 출현한 이후에---> 다음loop로 빠져나가도록 해주는 selenium의 클래스는 3가지가 필요하다.
    image
    image
    - By. 대문자 ID

  2. WebDriverWait()를 쓰면, 무조건 html정보에 id = collapseTwo 이하의 태그들이 포함되어 있다.
    bs4는 그 정보를 가져온다. 마치 아래처럼 텍스트가 없는 것 처럼 보이나..
    빈칸이 너무 많아서... 콘솔을 오른쪽으로 돌려보면 있다

    image
    image


  3. 이제, 발의자 정보를 2차원 리스트에 추가로 append시킬 수 있도록
    1) append구문을 bs4로 스크래핑 한 뒤쪽자리로 옮기고
    image
    2) pandas의 칼럼 역시 추가해준다. 이 때, 수기로 추가해주자.
    image

    저장된 엑셀파일을 확인하면 아래와 같다. 하지만,,, 빈칸이 너무나도 많다.
    image


  4. 빈칸을 없애주기 위한 .replace( ' ', '')
    image


  5. 마지막으로 page를 수정해서 10page까지만 해보자.
    image
    image

프로젝트 : web_scraping_study_no1
파일명 : watch_court.py

requests 패키지 설치 및 requests.get('') 이용하여 홈페이지에서  주소 가져오기

  • 어떤 사이트의 게시판에 들어갔을 때, request url이 안뜰 수 있다.
    image

    - 이럴 때는, 게시판의 2번째 페이지를 눌러서, 다시 1페이지로 오자.

    image
    image

  • 이제 파이썬 파일을 하나 만들고, bs4를 import한 뒤, reponse에다가 requests.get()의 인자에다가
    홈페이지 url을 담아주자.
    image


  • 여기서 빨간줄이 뜨는 이유는 requests.get()함수를 사용하기 위한 패키지가 필요하기 때문이다.
    설정 > interpreter > requests 를 검색해서 패키지를 설치하자.
    *** request가 아니라 requests
    image

    image


  • requests 패키지를 import하고 url은 문자열로 담아주자.
    image

  • response에서도 .text만 받아서 html 변수에 넣어준 뒤,
    html변수에 담긴 것을 print해보면 잘 나오는 것 같다.
    image


requests로 긁어온 html(문자열)을  bs4를 이용해서 정보 빼내기

  • 이전시간과 같이, soup변수에 "lxml"parser를 사용한 beautifulsoup()를 이용해서 정보를 가져오고,
  • soup에서 body만 가져와보자
    image


  • 하지만 body의 양이 방대하게 많으므로, 우리가 필요한 정보만
    해당 사이트 [ Ctrl + u ] 를 이용해서 게시판의 첫번째 글을 검색하여 위치를 찾아보자.
    image
    image

  • 이제 저 부분의 html코드 구조를 파악해야한다.
    • <td>는 한칸이다. ->  한줄을 의미하는 <tr>이 있을 것이다.
    • <tr> = 한줄 상위에는 table이 있을 것이다. 머리말이 있는 게시판이면 ->     <thead>와 <tbody>가 있을 것이다.
    • <thead>바깥에 <table>이 있을 것이다.
    • <table>바깥은 봤더니 ->   구획을 나누어주는 <div>태그 + id속성이 같이 있다.
    • id = 속성은 한 페이지당 단 1개를 특정짓는 것이므로 id = "ea_list"를 가진 <div> 집중공략할 준비를 한다.
      table(게시판)은 한 페이지에 여러개가 있을 수 있기 때문에,
      ==> ea_list라는 id를 가진 <div>태그를 먼저 찾자!


  • body.find(id=) 함수를 이용해, div태그를 적어주는 것 없이 바로 그 위치를 찾아, 그 아래구조들을 다 찾아준다.
    변수명은 div태그까지 포함시켜서 만들어 구조를 파악하기 쉽게해준다.
    image


  • id = 'ea_list'로 검색한 결과는 <div>태그 부터 시작한다.
    div -> table -> tbody 까지 내려가자. 그 안의 tr/td를 받아올 것이다.
    image


  • tbody속에는 여러개의 tr태그를 가지고 있기 때문에,
    .find_all('tr')을 통해 tr들을 다 가져온 뒤 : lines --> for문으로 한줄씩 받은 것을 print로 확인하자.
    image

  • 각 tr안에서도 여러개의 td들을 가지고 있다. ---> find_all('td')를 통해 td들을 개별적으로 다 받아오자.
    • for문 속 각 tr(line)들에 대해    여러개의 tr을 받아오고, 그 중 첫번째 칸만 출력해보자.
      - 날짜 정보는 우리가 원하는게 아니다.
      image

    • 2번째 칸을 출력해보고, 맞으면 .text를 붙혀서 텍스트 정보만 가져오자.
      image

      image


  • for문 안에서 원하는 정보를 각 루프마다 확인했다. 이것을 계속 쓸 수 있는 변수에 받기 위해 for문 전에 미리 리스트를 생성해야하고,
    각 루프속에서 append()로 넣어줘야할 것이다.
    image


  • 이 때, [ 날짜, 의안, 작성자 ]의 3개의 정보 한묶음으로 --> bill_list로 정보를  전달해주려면
    그러므로 위 처럼 1차원 리스트가 아니라 2차원의 리스트형태가 되도록
    미리 리스트형태로  append( [  1, 2, 3] )
    를 해줘야, bill_list는 2차원 리스트가 될 것이다.
    *** 2차원 리스트를 이쁘게 확인하려면, for문을 써서 확인한다.
    *** 2차원 리스트로 만들어야만 -->  pandas에 담을 수 있고 --> 엑셀로 저장할 수 있다!***

    image


  • 한가지 정보를 더 추가해보았다(5번째 칸, 진행상태)
    image


가져온 2차원 리스트의 정보--> pandas에 담고 --> 엑셀로 저장하기

  • pandas 패키지 설치 및 import
  • pandas.to_excel() -> .xlsx 저장을 위한 : openpyxl 패키지 설치
    image
  • pd.DataFrame()으로 bill_list를 df에 담기  *2차원 리스트여야 df에 담을 수 있다!
  • pd.to_excel('bill.xlsx')로 저장하기
    image

    image


  • 엑셀파일을 열어보니,, 칼럼명이 없다.
    my) table -> thead -> th(머리말 한칸)들에서 가져오자.
    그리고 받은 정보를 pandas의 df생성시 columns=[]인자를 이용해서 적어주자.
    *** 그냥 손으로 적어줘도.. 될 듯..
    image

    image

  • my) index(행 번호)도 옵션으로 주어 없애보자.
    image

    image



한 페이지가 아니라 여러 페이지를 다 해보자.

맨 처음 홈페이지 주소를 가져온 url 에서 page=1 ---> page2, 3, 4, ...로 바뀌어야할 것이다.

image

  • 이럴 때, 해야할 게, '문자열' 이므로    '  {} ' . format( i )을 이용하여 변수로 둔 다음, for문으로 돌리는 것!
    이 때 조심해야할 사항이 있다.
    image

    1. for문은 range(1, 100) --> 1page부터 시작할 것

    2. bill_list()는 page를 돌리는 for문보다 더 바깥으로 빼야한다. * 페이지를 돌면서 계속 append될 것
      image

    3. pandas에서 엑셀로 저장하는 부분은 for문 안에 안들어갈 것.
      image

  • 100page 모두 스크래핑 한 결과
    image


프로젝트명 : web_scraping_study_no1
html : example.html
py : web_scrapping_example.py

지난시간에 배운 HTML 기본코드를 바탕으로 py.파일을 생성하고 인터프리터에 beautifulsoup를 추가해보자.


BeautifulSoup4 설치하기

image
image

아직 라이브러리를 설치하지 않아서 빨간줄이 뜬다.

  • BeuatifulSoup 설치하기 *프로젝트를 새로 생성함과 동시에 가상환경을 만드므로, 인터프리터는 새로운 상태임(anaconda꺼 선택도 가능)
    - file > setting ( Ctrl + Alt + S ) > Project > Project Interpreter > 우측 초록색 + 버튼 >
    > beautifulsoup4( 그냥 beautifulsoup 아님!!!) > install package
    image
    image
    image
    image


bs4를 사용하여 example.html 스크래핑 해보기

html 객체에 예제 html코드를 넣어야하는데, 이 때 사용되는 것이 작은 따옴표 3개(''')이다.
이안에다가 여러줄의 String을 하나의 String으로 입력할 수 있다.

원래는 서버의 홈페이지에서 받아와야하는 html코드인데 ,여기서만 예시로 하는 것이다.
image
image
image


# 서버에서 받은 html코드를 이용하여 BeautifulSoup객체를 만드는데, 
# 받아올 때 필요한 양식이 "lxml"이며, 인스톨이 필요하다
  • lxml 패키지 설치

image

image


  • 이제 이 soup 객체에서 body만 꺼낼 수 있다.
    image

  • 다음으로 body안에서 h1만 꺼낼 수 있다
    image

    뒤에 .text를 붙히면 h1태그안의 텍스트만 꺼낼 수 있다.
    image


  • 다음으로 body태그안에 table을 꺼내보자.
    image

  • table은 특별히 thead와 tbody 태그를 나누어줬었다.
    tbody안에도 여러개의 tr(줄)이 존재했다. 여러개의 태그를 받을 때는 .find_all('태그명') 으로 받아온다.
    image

    tbody안에 tr들을 리스트로 받고,
    리스트를 이용한 for문으로 각 tr(줄)에 존재하는 여러개의 td(칸)들 중 첫번째 칸만 확인해보자.
    image

    뒤에 .text를 붙히면 태그안의 문자열만 가져올 수 있다.
    image

단축키 설정 방법

File > Setting > Keymap > 검색

image

단축키 목록

  1. 파일 생성 : alt + insert
  2. 한 줄 실행 : alt + shift +e   / my) ctrl + enter
  3. html미리보기창 : alt + F2
  4. 변수명 바꾸기(다같이) : shift + F6
  5. ctrl + alt + s : 환경설정
  6. keymap > show in explorer  :  alt + down wheel 로 최초설정
  7. shift + f10 : 실행
  8. `ctrl+shit+T` : for, if 문등으로 감싸기 선택
  9. ctrl +shit+/ : 블록단위주석(html주석시 편함)


HTML 이해해보기


image

  1. 위의 사이트와 같이 게시판 글을 긁어오고 싶다. 먼저, 크롬창을 띄운 상태에서 [ Ctrl + U ] 를 해보자.
    image
    - html 소스코드가 보인다.

  2. 게시판의 글 아무거나 하나를 복사한 뒤, 소스코드에서 검색해보자.
    image
    - html 태그안에 갖혀있는 것을 확인할 수 있다. 이정보들을 가져와야한다.

  3. 파이참에서 프로젝트를 생성하고,
    Alt+ insert를 통해 HTML file을 하나 만들어보자. 아래와 같이 기본 양식이 형성되어있다.
    image
    image


  4. [ Alt + F2 ] 혹은 코드창 우측상단에 뜨는 브라우저를 통해 한번 띄워보자.
    image
    image
    image
    - Title만 있고뜨고, 아무 화면도 뜨지않는다.

  5. HTML 구성에는
    크게 <html>태그 안에
    <head>태그와 <body>태그가 있고,
    <head>태그 안에는 <title>태그가 있다.

  6. <title>태그를 바꿔보고,
    <body>태그 안에는
        <h1>태그로서 제일 큰 글자를 적어보자.
        <h2> 조금더 작은 글자를 적어보자.
        <p>은 제목이 아닌, 단순 문단을 의미한다.
    image
    image

  7. 마찬가지로 <body>태그안에서,
    <table>태그를 만들어보자. table 태그는 벌려서, 안에 여러 태그를 포함시킨다.
         <tr>태그는 table안에서 한 줄을 의미한다.  벌려서 <td>태그를 포함한다.
             <td>를 한 칸을 의미한다.
    image
    image


    같은 <tr>태그 안에 <td>를 여러개 쓰면, 옆으로 한칸씩 붙는다.
    image
    image


CSS를 Bootstrap을 이용하여 작성하기

  • 위에서 작성한 table은 모양이 안이쁘다. 그래서 대부분
    <head>안에 css를 작성하며,
    css를 쉽게 작성하기 위해서 bootstrap을 이용할 수 있다.
    사이트는 [ 부트스트랩 와치.com ] : https://bootswatch.com/ 을 이용한다.
    image


  • 사용법은, Themes > 아무거나 선택 > Ctrl + U 를 통해, <head>태그 안에 있는 모양 정의 태그를 복사해오는 것이다.
    - 이 때, ...으로 줄여진 정보는, 클릭해서 해당 사이트에 접속 후, 그 주소를 복사해서 가져오면 된다.
    image
    image
    image
    image

    image
    - 클릭후 사이트 주소 전체 복사하기
    image
    image

    image
    image


    Before
    image

    Bootstrap - Darkly themes 적용 after
    image


이제 CSS를 이용해서 table모양을 바꿔보자.

  • <table>태그에 class="table" 속성(css에서 온 정보)을 넣어주면, 아래와 같이 바뀐다.
    image
    image

  • <table class="table">의 따옴표에 이어서 table table-striped 까지 넣어주면, 줄무늬가 생긴다.
    image
    image
    image


  • 표의 머리말을 굵은 글씨로 넣어주고 싶다면,
    (1) <thead>태그를 생성후 -->
               <tr> 한줄 안에 -->
                  <th> 로 한 칸씩 채운다.
    (2) 기존 내용들을 <tbody>안에 채워넣는다.
    image
    image

프로젝트명 : studying_pandas
차트 그리는 py : pandas_excel.py

  • pandas의 df(DataFrame)으로 차트를 그리려면, matplotlib이라는 모듈이 필요하다. 이전과 같은 방법으로 설치하자.
    image_thumb1

  • 설치가 되었으면,
    • import matplotlib을 통해서 모듈을 가져온다. -> 사실상 지금은 필요없다...
    • import matplotlib.pyplot as plt 를 통해 내부 파이플롯이라는 클래스를 plt로 가져온다.
      -> df의특정열.plot()을 통해 차트를 그린다.  ->  plt.show 로 화면에 띄운다.
  • 특정열(만두생산)을 .plot()을 통해 kind는 bar 차트로 그리고
    plt.show() 로 화면에 띄워보우는데, block을 띄울껀지인자를 True로 주자..
    -df['만두생산'].plot(kind='bar')
    - plt.show(block=True)
    *우측에 있떤 SciView를 설정 > FloatingMode를 통해 창으로 확인할 수 있다.
    image_thumb6
    image_thumb8
    - 여기서 x축이 이름이 아니라, index로 뜬다.

  • plot()을 차트로 그리기전에, 항상 띄울 DataFrame을 미리 print로 찍어보자.
    - x축으로 나올 index가 숫자로 찍혀있다.
    image_thumb1[1]

  • index를 0,1,2,3,4가 아니라, '이름'열로 하고 싶다.
    df.set_index('칼럼명')으로 특정칼럼을 -> index로 옮겨보자( df자체를 먼저 바꾸는 작업이다)
    image_thumb3


  • 다시 .plot()으로 출력시켜보자.
    이제 문제는 index여서 x축으로 출력되는 한글이 깨지는 문제

    1. 인코딩 문제
    2. 폰트가 영어만 써지는 폰트
    image

  • matplotlib에서 제공하는 font_manager를 통해 폰트를 설정해보자.
    1. 컴퓨터에 설치된 폰트의 이름을 가져오게 한다. -> 2. matplotlib함수에 적용한다.
    from matplotlib import font_manger를 통해 font_manager를 사용할 수 있게 한다.
    폰트매니져의, 폰트프로퍼티스의 인자로 폰트네임fname=실제 한글 폰트의 경로를 지정해주고 .get_name()을 붙혀 해당 폰트의 name을 가져와 font_name이라는 변수로 받는다.
    그리고 나서 matplotlib.rc('font', family= font_name)함수를 이용해서(드디어 쓰이네..) 차트의 폰트를 지정해준다.
    image

  • #matplotlib의 폰트를 지정해주는 방법
    font_name = font_manager.FontProperties(fname='C:/Windows/Fonts/malgun.ttf').get_name()
    matplotlib.rc('font', family=font_name)
    • 윈도우 환경에서는 c:/windows/fonts/ 폴더가 폰트가 있는 경로이다.
      모든 윈도우에 기본적으로 다 있는 malgun.ttf 를 사용할 것이다.
      image

  • 다른 칼럼을 그리고 싶다면, 최종df에서 df['만두생산'] -> df[' 다른칼럼명'] 으로 바꿔주면 될 것이다.
    차트를 저장하는 함수도 존재한다. plt.savefig('파일명*.png')을 통해 png파일로 저장해보자.
    반드시 plt.show(block=True)로 화면에 띄우기전에 저장해야한다. 순서가 바뀌면(show->savefig) 빈파일이 저장된다.
    image
    image
    image

pandas_excel.py
불러올 엑셀파일 : mandoo_management.xlsx
저장된 엑셀파일 : result.xlsx

  1. 새로운 파이썬 파일을 만든다.
  2. 불러올 엑셀파일을 만들고, 해당 프로젝트(studying_pandas)에 mandoo_management.xlsx 엑셀파일을 저장하자(csv아님)
    image
  3. 이제 파이썬에서 pandas모듈을 이용해 엑셀파일을 불러오고, 테스트로 출력까지 해보자.
    - df = pd.read_excel('mandoo_management.xlsx', sheet_name='Sheet1')와 같이
    Pandas -> DataFrame으로 불러오는데, pd.read_excel()함수를 사용하고, 인자에는 ('파일명', sheet_name='시트명')이 필요하다
    *엑셀의 기본시트명은 Sheet1 이다.
    - 불러온 것을 print(df) 으로 확인하려 했더니, install xlrd라는 어떠한 Excel support가 필요하다고 에러가 난다.
    image

  4. Settings > Project Interpreter > + > xlrd를 검색해서 설치하고, 다시 출력시켜보자.
    image
    image

    확인해보았더니, 판다스에서는 첫row를 자동으로 칼럼명으로 인지한 것을 확인할 수 있다.

    CSV를 다룰 때는,
    읽을 때, 첫ROW를 제외하고
    쓸때는 첫ROW를 따로 쓰고 나머지를 FOR문에서 썼다.

  5. 첫row로 인지된 칼럼명row 중 하나의 칼럼을 출력시켜보자
    - print( df['칼럼명'] )
    image

  6. 출근시간 퇴근시간 칼럼을 이용하여, 근무시간 칼럼즈를 추가해보자
    - df['근무시간'] = df['퇴근시간'] - df['출근시간']
    image

    마찬가지로, 시간당 만두생산 칼럼을 추가해보자.
    - df['시간당 만두'] = df['만두생산'] / df['근무시간']
    image


  7. 이제 시간당 만두를 잘만드는 사람의 순위를 메겨보여주도록 해보자.
    특정 칼럼을 기준으로 df를 새롭게 위치시켜 보여준다.
    df.sort_values()함수로 정렬을 하는데,
    by=['칼럼명']  -> 해당칼럼을 기준으로 정렬한다.
    ascending=[False] -> 오름차순을 False로 두어, 내림차순으로 정렬된다.

    - df = df.sort_values(by=['시간당 만두'], ascending=[False])

    image

    기준칼럼이 똑같은 경우에는, 2순위의 칼럼을 지정할 수 있다. 이 때, ascending인자에도 False로 내림차순 만들어줘야한다.
    위에서는 시간당만두가 100.0 으로 같은 조재성과 안철수 중 근무시간은 안철수가 더 많다.
    - df = df.sort_values(by=['시간당 만두' , '근무시간' ], ascending=[False, False])
    image

  8. DataFrame이 완성되었다면, 엑셀로 저장할 수 있다. 마찬가지로 시트명을 같이 명시해줘야한다.
    - df.to_excel('result.xlsx',  sheet_name='Sheet1)
    바로 실행시키면 아래와 같이 openpyxl모듈이 없다고 뜬다. 마찬가지로 설치해주면된다.
    image
    image
    image
    image


결론적으로, 기본 엑셀파일이 -> pandas를 거쳐 ->

계산식을 통한 새로운 칼럼 추가 & sorting(1순위>2순위)이 되어서 저장


pandas에서 엑셀파일을

열때는-->  xlrd

저장할 때는--> openpyxl

모듈이 필요했다.

pandas_basic.py

Pandas

엑셀로 다 할 수 있겠지만, 파이썬 & pandas를 사용하면 반복되는 업무 큰 데이터를 쉽게 다룰 수 있다.
판다스 공식 홈페이지

사용해보기

새로운 프로젝트를 만들어보자. (studying_pandas)
새로운 파이썬 파일을 만들자.(pandas_basic.py)


  1. 먼저, 판다스 모듈을 설치해야한다. pip로 하는 방법도 있겠지만,
    File> Settings [ Ctrl+ Alt +S ] > Project : ~ > Project Interpreter > + > pandas를 검색해서 설치한다.
    - pandas를 설치하면, Numpy 와 matplotlib을 함께 설치하므로 많은 시간이 걸린다.
    image

  2. pandas_basic.py에서 import pandas를 하자.
    Numpy에서 array를 주로 사용했다면,
    pandas에서는 DataFrame을 가장 많이 사용한다.
    인자로는 df= pandas.DataFrame( [    [1,2,3], [4,5,6]   ]) 와 같이, 리스트안에 리스트가 들어가는 것이 DataFrame이다.
    - 출력해보면, 행렬처럼, 엑셀형태처럼 나온다.
    image


  3. 칼럼즈에 대해서 먼저 print를 해보자.
    - df.columns 를 print해보면, 0부터 3 까지, 스텝은 1씩 올라간다
    df.columns =  [리스트] 형식으로 칼럼명을 대입해보자.
    - 칼럼명이 바뀐다.
    imageimage

  4. 인덱스도 마찬가지로 리스트형식으로 대입해준다.
    - df.index = [ 리스트 ]
    image

  5. DataFrame 선언과 동시에 columnsindex를 지정해줘도 된다.
    image


  6. pandas를 import할 때, pd로 줄여서 입력시킬 수 있다.
    - import pandas as pd
    image


  7. 새로운 칼럼즈을 추가해보자.
    추가는 그냥 DataFrame[ '칼럼명' ] 만 해주면 새로 생성된다. 여기에 a열과 b열을 뺀 값을 넣어보자.
    - df['d'] = df['a'] - df['b']
    image


  8. 인덱스(행)를 추가할 때는, 기존 df에다가 새로운 것을 대입하는 방식으로 하는데,
     df = df.append()로 추가하는데, 기존인덱스를 무시해야지만 추가 할 수있다.
    만약, 각 열의 합을 요소로 가지는 행을 추가한다면, 인자로 df.sum()를 해주면 된다.
    - df = df.append( df.sum(), ignore_index=True)
      *만약 행 추가시, ignore_index 옵션을 안주면 에러난다.
    image

    무시되어, 0부터 차례되로 출력되는 index는 다시 df.index = [리스트]로 index값을 넣어주면된다.
    image

csv_to_python_to_csv_practice 프로젝트 : practice_by_csv_module.py
나의 클래스 모듈 : employee.py
시작 엑셀(csv)데이터 : emplyee_list.csv
시작 문서 양식(form) : form.docx ( 제목0,1,2  / paragraph / circle , check)
-시작 문서 양식 내용포함(form) : form_save.docx
결과 엑셀(csv)데이터 : result.csv
결과 문서(docx)데이터 : result.docx

image_thumb2

  1. 엑셀형태로 구성하고 싶은 데이터가 있다고 가정하고,  칼럼들을 클래스의 필드로 만든다.
  2. 상수를 제외하고, 생성자로 정의하여 클래스( , , , )로 인스턴스생성과 동시에 입력받도록 해준다.
    *만약, 상수로 먼저 선언하고서, 인자로 받아도 되고, 안받아도 되도록 설정하려면,
    (1) 생성자의 인자로서 wage_per_hour = None으로 default로 둔다.
    (2) 기본적으로 self.wage_per_hour = wage_per_hour는 바로 입력하지 않고,
    (3) if wage_per_hour: 를 통해 default인 None이 아닌 값이 넘어와서 True를 가질 때,
         상수였던 필드(wage_per_hour = 7530) 에 self.wage_per_hour = wage_per_hour를 대입하도록 한다.
      image_thumb5_thumb_thumb

  3. 칼럼 중에 함수식이 필요한 것은, 클래스 내부의 함수로 정의하여 self.필드들을 이용해서 (return에다가) 계산식을 만든다.
    ex> 퇴근시간 - 출근시간 = 근무시간
  4. 만약, 함수식 계산을 한 칼럼에 또 함수식을 써야하는 경우에는
    클래스에 정의된 함수식을 또 호출하는 함수를 생성하면 된다. 필드와 마찬가지로 return에다가 self.함수()로 호출해서 계산식을 만든다.
    ex> 일당 = 근무시간(퇴근시간 - 출근시간) * 시급
  5. 클래스를 정의한 부분을 모듈화 시키기 위해
    (1) 새로운 파이썬 파일 : employee.py 를 만들고
    (2) 클래스 정의 코드를 잘라내서 붙혀넣는다.
    (3) 기존 파이썬 파일에서는 from employee(파이썬 파일) import Employee(클래스명)으로 가져온다.

    ------CSV 읽어들이는 코드-----


  6. 이제 인스턴스 인자로 들어갈 데이터들을 엑셀파일에서 받아오기 위해, CSV (쉼표로분리)로 프로젝트내에 다른이름 저장
  7. f = open('파일명.csv', 'r')를 통해 열고 / f.close()도 미리 같이 작성
    f.readlines()를 통해 각 row을 list로 받음 -> (리스트이므로) for문을 통해 개별 출력시켜본다.
    import csv 를 통해 모듈을 가져온다(아나콘다로 설치시 미리 깔려있음)
    lines = csv.reader(f)를 통해 csv의 모든 라인을 리스트로 받아온다( f.readlines()와 달리, 4개로 미리 쪼개어져있다)
  8. 첫 줄은 칼럼명row이므로, 2번째줄 부터 읽기 위해선, while문과 비슷하게
    i =0 작성 -> for안에서 읽어진 lines를 i > 0부터 콤마로쪼개는 작업 등등을 하도록 하고, for문 마지막에 i += 1를 달아준다.
  9. 각 리스트는 콤마(,)를 통해 4개의 요소가 붙어있으므로 .split(',')를 통해 다시 리스트로 쪼개어 받는다.
    4개로 쪼개진 요소를 담는 list를 for문을 돌면서 출력시켜본다.

    4개 요소를 담고 있는 리스트는 리스트[0], [1], [2], [3] 형태로 개별접근이 가능해진다.
  10. 이제 for문을 돌면서 4개의 요소를 입력받아 생성될 인스턴스들을 관리할 리스트를 for문전에 만든다.
    ex> employee_list = []    or   employee_list = list()
  11. for문을 돌면서, 인스턴스관리 리스트에 .append()안에 인스턴스를 생성하면서, 생성자4개를 입력해준다.
    ex> employee_list.append( 클래스( 필드[0], 필드[1], 필드[2], 필드[3]) )
    * 이 때, csv에서 받은 요소들은 모두 문자열로 가져온다. 정수 데이터인 출근시간, 퇴근시간, 시급int()로 감싸주어야 클래스에서 계산된다.
    ex> employee_list.append( 클래스( 필드[0], int( 필드[1]), int(필드[2]), int(필드[3]) ) )
  12. 인스턴스관리리스트를 확인해보기 위해
    (1) print(len())로 전체 길이를 살펴보고
    (2)  <리스트를 이용한 for문>을 통해, 세부적으로 인스턴스 안의 필드나 함수를 하나씩 확인하는데, 
    print()로 , {}\t{}\t .format( 인스턴스.필드1, 인스턴스.필드2,.., 인스턴스.함수1(), 인스턴스.함수2(),) 형식으로 한 줄로 출력해보자.

  13. csv파일쓰기위해, 위에서 인스턴스 필드/함수 세부 확인한 print문을 고치면 된다. print->write 수정시 줄바꿈을 항상기억 + 칼럼명row출력
    (1) for문 전에 open()  '파일명', 'w' 이 들어갔다. + 3번째 인자로서, newline=''을 넣어줘야, csv_writer.writerow([])후에 자동 줄바꿈이 x
    (2) for문 전에 csv_file.write( 칼럼명row \n')
        csv_writer = csv.write(f)를 통해 쓰기 변수를 생성해준다.
        첫줄(칼럼명)은 csv_writer.writerow( [ 배,열,형,태] ) 로 넣어준다. 줄바꿈은 안해줘도 자동으로 된다.
    (3) for문 안에 print-> csv_file.write csv_writer.writerow([ , , , ]) 로 고치고,  새로운 칼럼{} 만들어주고, \t 를 콤마(,)로 수정하고,    \n줄바꿈 해주기
    (4) for문 끝나면 close()


    ----- 문서화 하는 코드 -----



  14. 12강 자료를 이용해, docx형식의 양식 파일(form_save.docx)을 만든다. -> 편의성을 위해, 내용은 지운다(form.docx)
  15. [설정 > Project Interpreter ]에서 add를 통해 [python-docx]를 검색하여 모듈을 추가한다
  16. docx_practice.py를 참고하여
    • import / 양식파일을 포함한 Document객체 생성 / 제목을 넣는다
    • 제목1 수준으로 소제목을 만든 뒤, 
      본문 수준으로 리스트를 작성해보자.
      인스턴스관리 리스트를 이용한 for문으로 각 행의 정보(각 인스턴스.필드, 함수)를 뽑아내는데,
      .format을 활용하여 문장형식으로 작성해보자
  17. 제목2수준으로 하나 넣어준 뒤, table을 생성해보자
    • table객체는 document.add_table( rows=1, cols=6 )로 한 행씩 몇개의 정보가 들어가는지 더해가는 기준을 만든다.
    • table.style = ' ' 로 미리 문서양식에서 만든 사용자지정양식을 기입해 스타일을 지정한다
    • 첫 행for문 전에 미리 작성해준다. 첫 행table.rows[0].cells를 통해 첫 행들의 각 셀들리스트 변수로 받아준다.
      받은 첫 행의 각 셀들의 리스트변수[0], [1].text, .. 형식으로 접근하여 문자열형식칼럼명을 적어준다.
    • 2번째 행부터는 정보가 들어가므로, 인스턴스관리 리스트를 이용한 FOR문에서 table.add_row().cells 로 각 셀들을 변수로 받는다
      그리고 각 셀들을 리스트요소 접근방식으로 접근 하되, 마찬가지로 .text를 붙히고 str( 인스턴스.필드, 함수()) 형식으로 문자열만 오로지 대입한다.
      만약, 정수로 표현되야 한다면 str()안에 int()로 감싸준다
  18. 저장은 document.save('파일명')으로 한다.

mandoo_wage_calculator.py에서는 employee.py의 Employ클래스를 가져다 쓰고있는 상태였다.

  1. 먼저 from docx import Document
  2. Document('양식.docx')로 변수를 생성해주는데, 인자에는 양식.docx를 지정해준다.
    동시에, 까먹지 않도록, document.save('저장할 파일명.docx')를 지정해준다.
  3. 그 사이에다가 document.add_heading('', 0)을 통해 제목(0)을 작성해주고, 확인해보자
    image_thumb5
    image_thumb8

  4. 출근한 직원인스턴스관리 리스트를 이용해 for문을 이용해 뽑아보자.
    - '{}님은 {}시 출근, {}시 퇴근'.format( 인스턴스.필드, ~~) 형태로 문장형태로 작성할 수도 있다.
    image_thumb14

    image_thumb15
    image_thumb22
    image_thumb24

  5. docx_practice.py에서 연습했던 테이블작성 코드를 가져와서, 근무시간, 일당을 포함한 테이블을 작성할 수 있다.
    * 자료가 담긴 인스턴스들을 관리하는 employee_list를 이용한 for문에서,  각 인스턴스.필드들을 -> 각 셀에 대입해주는데
    각 셀 접근[n].text  = str( 인스턴스.필드) 형식으로 문자열만 입력 가능하다!
    image_thumb30
    image_thumb32

  6. 시급과 일당 같은 경우, 정수로 표현되어야 하므로, str()안에 int()로 변환시킨다.
    image_thumb34
    image_thumb40


  7. 이제, input이 되는, employee_list.csv 파일을 수정하여서 바뀌는 상황을 살펴보자.
    1. employee_list.csv 에 row 추가
      image_thumb45

    2. 파이참에서 프로젝트 실행
      image_thumb49


    3. 자동으로
      (1) 근무시간 계산(노동법 고려) 과 일당 계산한 csv파일 생성 ( employee_result.csv)
      image_thumb51
      (2) 자동으로 MS WORD의 docx문서 생성( mandoo_wage.docx)
      image_thumb58

+ Recent posts