지난번 포스팅에서는 파일을 열고(open), 파일을 읽고(read), 쓰고(write), 닫기(close)를 하는 방법을 소개하였습니다.  

 

이번 포스팅에서는 Python 에서 

 

(1) 문자열로 이루어진 리스트를 텍스트 파일에 쓰기

    - (1-1) 한 줄씩 쓰기 : write() 메소드 (for loop 문과 함께 사용)

    - (1-2) 한꺼번에 모든 줄 쓰기 : writelines() 메소드

 

(2) 텍스트 파일을 읽어오기

    - (2-1) 텍스트를 한 줄씩 읽어오기 : readline() 메소드 (while 문과 함께 사용)

    - (2-2) 텍스트를 한꺼번에 모두 읽어오기 : readlines() 메소드

 

에 대해서 소개하겠습니다. 

 

 

 (1-1) 문자열로 이루어진 리스트를 한 줄씩 텍스트 파일에 쓰기 : write() 메소드

 

 

 

예제로 사용할 텍스트는 영화 매트릭스(movie Matrix)에서 모피어스가 네오에게 말했던 대사 (Morpheus Quotes to Neo) 중 몇 개로 이루어진 파이썬 리스트입니다. '\n'으로 줄을 구분하였습니다. 

 

 

matrix_quotes = ["The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n", 

                 "You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n", 

                 "There is a difference between knowing the path and walking the path.\n", 

                 "Welcom to the desert of the real!\n"]

 

 

* image source: https://www.elitecolumn.com/morpheus-the-matrix-quotes/morpheus-the-matrix-quotes-4/

 

위의 텍스트 문자열로 이루어진 'matrix_quotes' 리스트를 'matrix_quotes.txt'라는 이름의 파일에 한 줄씩 써보도록 하겠습니다. 먼저 with open('matrix_quotes.txt', 'w') 함수를 사용해서 'matrix_quotes.txt'라는 이름의 파일을 '쓰기 모드('w')'로 열고, 모두 4줄로 이루어진 리스트이므로 for loop 순환문을 이용해서 한줄 씩 line 객체로 가져온 다음에 f.write(line) 메소드로 한 줄씩(line by line) 'matrix_quotes.txt' 텍스트 파일에 써보겠습니다. 

 

 

with open('matrix_quotes.txt', 'w') as f:

    for line in matrix_quotes:

        f.write(line)

 

 

* 참고로, with open() 함수를 사용하면 close() 를 해주지 않아도 알아서 자동으로 close()를 해줍니다. 

* with open('matrix_quotes.txt', 'w') 에서 'w' 는 쓰기 모드를 의미합니다. 

 

 

현재 Jupyter notebook을 열어서 작업하고 있는 폴더에 'matrix_quotes.txt' 텍스트 파일이 생성되었음을 확인할 수 있습니다. 

 

 

 

 

for loop 문과 write() 메소드를 사용해서 텍스트를 파일에 쓴 'matrix_quotes.txt' 파일을 더블 클릭해서 열어보니 Python list 의 내용과 동일하고, 줄 구분도 '\n'에 맞게 잘 써진 것을 알 수 있습니다. 

 

 

 

 

 

 (1-2) 문자열로 이루어진 리스트의 모든 줄을 텍스트 파일에 쓰기: writelines() 메소드 

 

그런데 위의 write() 메소드의 경우 여러 개의 줄이 있을 경우 for loop 반복 순환문을 함께 써줘야 하는 불편함이 있습니다. 이때 writelines() 메소드를 사용하면 리스트 안의 모든 줄을 한꺼번에 텍스트 파일에 써줄 수 있어서 편리합니다.  위의 (1-1)과 동일한 작업을 writelines() 메소드를 사용해서 하면 아래와 같습니다. 

 

 

matrix_quotes = ["The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n", 

                 "You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n", 

                 "There is a difference between knowing the path and walking the path.\n", 

                 "Welcom to the desert of the real!\n"]

 

 

with open('maxtix_quotes_2.txt', 'w') as f:

    f.writelines(matrix_quotes)

 

 

 

Jupyter notebook을 작업하고 있는 폴더에 가서 보니 'matrix_quotes_2.txt' 파일이 새로 잘 생성되었습니다. 

 

 

 

 

 

  (2-1) 텍스트 파일을 한 줄씩 읽어오기 : readline() 메소드

 

이제는 방금전 (1-1)에서 만든 'matrix_quotes.txt' 텍스트 파일로 부터 텍스트를 한 줄씩 읽어와서 matrix_quotes_list 라는 이름의 파이썬 리스트를 만들어보겠습니다. 

 

 

 

readline() 메소드는 텍스트 파일을 '\n', '\r', '\r\n' 과 같은 개행 문자(newline) 를 기준으로 한 줄씩 읽어오는 반면에 vs. readlines() 메소드는 텍스트 파일 안의 모든 텍스트를 한꺼번에 읽어오는 차이가 있습니다.  따라서 한 줄씩만 읽어오는 readline() 메소드를 사용해서 텍스트 파일 내 모든 줄을 읽어오려면 while 순환문을 같이 사용해주면 됩니다. 

 

 

with open('matrix_quotes.txt', 'r') as text_file:    matrix_quotes_list = []    line = text_file.readline()        while line != '':        matrix_quotes_list.append(line)        line = text_file.readline()

 

 

 

matrix_quotes_list

[Out]: 
['The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n',  'You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n',  'There is a difference between knowing the path and walking the path.\n',  'Welcom to the desert of the real!\n',  '']

 

 

* 참고로 with open('matrix_quotes.txt', 'r') 에서 'r'은 '읽기 모드'를 의미합니다. 

 

 

만약 파일을 한 줄씩 읽어오면서 매 10번째 행마다 새로운 파일에 쓰기를 하고 싶다면 아래 코드 참고하세요. 

with open(in_name, 'r') as in_file:
    with open(out_name, 'w') as out_file:
        count = 0
        for line in in_file:
            if count % 10 == 0:
                out_file.write(line)
            count += 1

 

 

 

  (2-2) 텍스트 파일을 모두 한꺼번에 읽어오기 : readlines() 메소드

 

이번에는 readlines() 메소드를 사용해서 'matrix_quotes.txt' 텍스트 파일 안의 모든 줄을 한꺼번에 읽어와서 matrix_quotes_list_2 라는 이름의 파이썬 리스트를 만들어보겠습니다.  readlines() 메소드는 한꺼번에 텍스트를 읽어오기 때문의 위의 (2-1) 의 readline()메소드와 while 순환문을 함께 쓴 것도다 코드가 간결합니다. 

 

 

with open('matrix_quotes.txt', 'r') as text_file:

    matrix_quotes_list_2 = text_file.readlines()

 

 

matrix_quotes_list_2

[Out]: 
['The Matrix is the world that has been pulled over your eyes to blind you from the truth.\n',  'You have to let it all go, Neo. Fear, doubt, and disblief. Free your mind.\n',  'There is a difference between knowing the path and walking the path.\n',  'Welcom to the desert of the real!\n']

 

 

 

많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~

'를 꾹 눌러주세요. :-)

 

 

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 파이썬으로 


(1) 파일을 열고, 데이터를 쓰고, 파일을 닫기

(2) 파일을 열고, 데이터를 읽고, 파일을 닫기

(3) with open(file_name) as file_object: 로 파일 열고, 데이터를 읽고, 자동으로 파일 닫기

(4) open() error 처리 옵션 설정


하는 방법을 소개하겠습니다. 




파이썬으로 파일을 열 때 open() 함수를 사용하는데요, 1개의 필수 매개변수와 7개의 선택적 매개변수를 가지며, 파일 객체를 반환합니다. open() 함수의 mode 는 'w', 'r', 'x', 'a', '+', 'b', 't'의 7개 모드가 있으며, 위의 이미지 우측에 있는 표를 참고하시기 바랍니다. ('r' 읽기용으로 파일 열기't' 텍스트 모드로 열기가 기본 설정값입니다)



open(

  file,                 # 필수 매개변수, 파일의 경로

  mode = 'r',       # 선택적 매개변수, 'rt' (읽기용, text mode)가 기본값

  buffering = -1,   # 선택적 매개변수, 버퍼링 정책 (0 : binary mode 시 버퍼링 미수행, 

                        # 1: 텍스트 모드 시 개행문자(\n)을 만날 때까지 버퍼링)

  encoding = None, # 선택적 매개변수, 문자 인코딩 방식 (예: 'utf-8', 'cp949', 'latin' 등)

  errors = None,   # 선택적 매개변수, 텍스트 모드 시 에러 처리 (예: 'ignore' 에러 무시)

  newline = None, # 선택적 매개변수, 줄바꿈 처리 (None, '\n', '\r', '\r\n')

  closefd = True,   # 선택적 매개변수, False 입력 시 파일 닫더라도 파일 기술자 계속 열어둠

  opener = None) # 선택적 매개변수, 파일을 여는 함수를 직저 구현 시 사용

 




  (1) 파일을 열고 --> 파일에 데이터를 쓰고 --> 파일을 닫기


(1-1) MyFile = open('myfile.txt', 'w') : open() 함수를 사용하여 'myfile.txt' 파일을 'w' 모드 (쓰기용으로 파일 열기, 파일이 존재하지 않으면 새로 생성, 파일이 존재하면 파일 내용을 비움(truncate)) 열어서 MyFile 객체에 할당하고,  

(1-2) MyFile.write('data') : MyFile 객체에 'data'를 쓴 후에, 

(1-3) MyFile.close() : 파일을 닫습니다. 자원 누수 방지를 위해 마지막에는 꼭 파일을 닫아(close) 주어야 합니다. 


참고로, Windows 10 OS의 기본 encoding 은 'cp949' 입니다. 



# Open and Write

MyFile = open('myfile.txt', 'w')

MyFile.write('Open, read, write and close a file using Python')

MyFile.close()


# encoding = 'cp949' for Windows10 OS

MyFile

[Out] <_io.TextIOWrapper name='myfile.txt' mode='w' encoding='cp949'>

 



현재 작업 경로에 위에서 만든 'myfile.txt' 파일이 생성이 되어서 존재하는지 확인해보겠습니다. 



import os

os.listdir(os.getcwd())

[Out]:

['myfile.txt', 'Python_read_write_file.ipynb']

 




  (2) 파일을 열고 --> 파일의 데이터를 읽고 --> 파일을 닫기


(2-1) MyFile = open('myfile.txt', 'r') : 이번에는 (1)번에서 데이터를 써서 만들어놓은 'myfile.txt' 파일을 open() 함수의 'r' 모드 (읽기용으로 파일 열기, default) 로 열어서 MyFile 객체에 할당하고, 

(2-2) MyString = MyFile.read() : 'myfile.txt' 파일을 읽어서 MyString 객체에 데이터를 저장하고, print(MyString) 로 인쇄를 한 후, 

(2-3) MyFile.close() : 파일을 닫습니다. 자원 누수 방지를 위해 마지막에는 꼭 파일을 닫아(close) 주어야 합니다. 


# Open and Read

MyFile = open('myfile.txt', 'r')


# equivalent to the above

#MyFile = open('myfile.txt', 'rt')

#MyFile = open('myfile.txt', 't')

#MyFile = open('myfile.txt')


MyString = MyFile.read()

print(MyString)


[Out]: Open, read, write and close a file using Python


# close the 'MyFile' file

MyFile.close()



open() 함수의 7개 mode 중에서 'r' 읽기용으로 열기와 't' 텍스트 모드로 열기가 기본값이므로 위의 open('myfile.txt', 'r') 은 open('myfile.txt', 'rt'), open('myfile.txt', 't'), open('myfile.txt') 와 동일한 코드입니다. 




  (3) with open(파일 이름) as 파일 객체: 를 사용해서 파일 열기


with open() as 문을 사용하여 파일을 열면 마지막에 close() 함수를 명시적으로 써주지 않아도 자동으로 파일이 닫힙니다. 위의 (2) 번 코드를 with open(file_name) as file_object: 문으로 바꿔주면 아래와 같습니다. 



# Using the with statement the file is automatically closed

with open('myfile.txt', 'r') as MyFile:

    MyString = MyFile.read()

    print(MyString)

    # no need for MyFile.close()


[Out]: Open, read, write and close a file using Python

 




  (4) 텍스트 모드에서 인코딩, 디코딩 에러 발생 시 처리 : errors


가령, 파일에서 데이터를 읽거나 쓰는 와중에 에러가 발생했을 시 무시하고 싶다면 open('file.txt', 'rw', errors = 'ignore') 라고 설정을 해주면 됩니다. 


errors 매개변수 

error 처리 방법 

 'strict'

 인코딩 에러 발생 시 ValueError 예외

 'ignore'

 에러 무시

 'replace'

 대체 기호 삽입 (예: "?")

 'surrogateescape'

 U+DC80~U+DCFF 사이의 유니코드 사용자 자유 영역의 잘못된 바이트를 code points 로 나타냄

 'xmlcharrefreplace'

 파일을 쓸 때 파일에 기록하려는 텍스트 안의 지정된 인코딩에서 지원되지 않는 문자를 &#NNN; 의 XML 문자 참조로 바꿔서 기록

 'backslashreplace'

 파일을 쓸 때 현재 인코딩에서 지원되지 않는 문자를 역슬래시(back slash, \)로 시작되는 escape sequence로 바꿔서 기록



다음번 포스팅에서는 줄 단위로 텍스트 파일을 읽고 쓰는 방법을 소개하겠습니다. 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)


728x90
반응형
Posted by Rfriend
,

JAVA, C++, C#, Python, PHP 등을 사용하는 SW 개발자 중에 객체 지향 프로그래밍(Object-Oriented Programming, OOP)과 클래스(Class)를 모르는 분은 없을 것입니다. 


반면에, 통계와 데이터 분석을 전공하신 분들 중에는 객체 지향 프로그래밍과 클래스에 대해서 모르는 분이 상당히 많을 것이라고 보며, 아마도 '내가 개발자도 아닌데 객체 지향 프로그래밍과 클래스를 왜 알아야 해? 사용자 정의함수 만들어 쓸 수 있으면 되는거 아닌가?' 라고 생각하며 아예 선을 그어버리고 외면하는 분도 계실 듯 합니다. (제가 예전에 이랬거든요. ^^;)


그런데 통계/머신러닝 모델을 운영 시스템에 반영하기 위해 개발자와 협업하다보면 클래스 얘기가 나오고, 또 딥러닝 공부하다보니 자꾸 클래스와 맞닥드리게 되어서 이참에 클래스 공부도 하고 블로그에 정리도 하게 되었습니다. 


이번 포스팅에서는 통계와 분석업무 하시는 분들을 독자로 가정하고 파이썬3의 클래스(Class in Python 3)에 대해서 소개하겠습니다. 


1. 객체 지향 프로그래밍은 무엇이며, 클래스는 무엇인가? 

2. 왜 객체지향 프로그램이 필요한가?

3. 클래스와 인스턴스는 어떻게 만드는가? 

4. 클래스 상속이란 무엇인가? 

5. 클래스와 함수의 차이점은 무엇인가


ps. Private member, 상속의 super(), 다중 상속, decorator, iterator, generator, 추상 기반 클래스(abstract base class), Overriding 등의 세부 심화 내용은 이번 포스팅에서는 제외하겠으며, 파이썬 프로그래밍 개발 관련 전문 서적이나 사이트를 참고하시기 바랍니다. 



  1. 객체 지향 프로그래밍은 무엇이며, 클래스는 무엇인가? 


위키피디아에서 객체 지향 프로그래밍을 어떻게 정의하고 있는지 찾아보았습니다. 


객체 지향 프로그래밍(Object-oriented programming, OOP)은 객체(Objects) 개념에 기반한 프로그래밍 패러다임으로서, 변수(field) 혹은 속성(attribute), 특성(property)이라고 알려진 데이터(data)와 프로시져(procedures) 또는 메소드(methods) 형태의 코드(code) 를 가지고 있다. (Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).)


객체의 프로시져를 통해 객체의 연관되어 있는 데이터 변수들에 접근하고 변경할 수 있는 특성이 있다. (객체는 "this" 또는 "self"의 표기를 가지고 있다) (A feature of objects is an object's procedures that can access and often modify the data fields of the object with which they are associated (objects have a notion of "this" or "self").)


객체 지향 프로그래밍에서 컴퓨터 프로그램은 서로 상호작용하는 객체들을 만듦으로써 설계한다. 객체 지향 프로그래밍 언어는 다양하지만 가장 일반적인 것은 클래스 기반(class-based) 의 언어이다. 클래스 기반이란 클래스의 인스턴스가 객체가 되고 유형(type)을 결정하는 것을 의미한다. (In OOP, computer programs are designed by making them out of objects that interact with one another. OOP languages are diverse, but the most popular ones are class-based, meaning that objects are instances of classes, which also determine their types.)


* source: Wikipedia


말이 좀 어려운데요, 한번 더 정리를 해보자면, 

  • 객체(objects) = data (fields, attributes, properties) + code (procedures, methods)
  • code(procedures, methods) 를 통해 data(fields, attributes, properties)에 접근하고 변경 가능
  • class 로 data와 code를 겹합하며, 클래스를 구체화(실체화)한 인스턴스는 객체가 됨


Python도 객체 지향 프로그래밍을 지원하는 대표적인 언어이며, 위의 위키피디아 정의와 동일하게 객체는 속성(attribute)과 기능(method), 다른 말로 표현하면 객체는 변수(filed)와 함수(function)로 구성됩니다. 이들 속성(attribute)(또는 변수(field))와 기능(method)(또는 함수(function))을 클래스(class)를 사용해서 하나로 묶어줍니다. 클래스를 실체화하여 인스턴스(instance) 객체를 생성합니다. (아래 3번의 실제 예를 살펴보면 이해하기에 더 쉬울 것입니다)





  2. 왜 객체 지향 프로그램이 필요한가?


객체 지향 프로그래밍을 하면 객체(변수 + 함수) 내의 응집력은 강하지만 객체 간의 응집력은 약하게 하여 소프트웨어의 개발, 유지보수, 업그레이드를 보다 쉽게 할 수 있도록 해주는 장점이 있습니다. 


"객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다. 또한 프로그래밍을 더 배우기 쉽게 하고 소프트웨어 개발과 보수를 간편하게 하며, 보다 직관적인 코드 분석을 가능하게 하는 장점을 갖고 있다."

* source: wikipedia


"같은 목적과 기능을 위해 객체로 묶인 코드 요소(변수, 함수)들은 객체 내부에서만 강한 응집력을 발휘하고 객체 외부에 주는 영향은 줄이게 됩니다. 코드가 객체 위주로 (또는 순수하게 객체로만) 이루어질 수 있도록 지향하는 프로그래머의 노력은 코드의 결합도를 낮추는 결과를 낳게 됩니다."

* source: '뇌를 자극하는 파이썬3', 박상현 지음, 한빛미디어


아래의 클래스를 어떻게 만들고, 상속(inheritance)은 무엇인지를 알면 응집력에 대한 위의 내용이 좀더 이해가 쉬울 것입니다. 



  3. 클래스(class)와 인스턴스(instance)는 어떻게 만드는가? 




-- 클래스 정의 (create a Class) -- 

(a) 클래스 정의는 class 키워드 (keyword) 로 시작하고, 다음에 클래스 이름을 써주며, 뒤에 콜론(':')을 써줍니다. 


(b) 클래스 이름은 보통 대문자(capital letter)로 시작합니다. 

            아래 예) class PersonalInfo:


(c) 클래스의 코드 블락에는 

    (c-1) 클래스 전체에 공통으로 사용하는 클래스 속성(class attribute), 

            아래 예) nationality = "Korean"

   (c-2) 인스턴스별로 객체를 초기화해서 사용하는 인스턴스 속성(instance attributes)

            아래 예) def __init__(self, name, age):

                             self.name = name

                             self.age = age

   (c-3) 기능을 수행하는 인스턴스 메소드(instance methods) 를 정의합니다. 

            아래 예) def getPersonalInfo(self):

                             print("Name:", self.name)


(d) 인스턴스 객체의 속성을 초기화해주는 역할은 def __init__(): 의 마법 메소드(magic method) 를 사용합니다. 


(e) 'self'는 메소드가 소속되어 있는 객체를 의미합니다. ( C++, C#, JAVA 의 'this'와 동일한 역할)


-- 인스턴스 객체 생성 (create an instance object) --

(g) 클래스 이름(변수 값) 생성자로 클래스를 구체화/ 상세화한 인스턴스(instance)를 정의합니다. 

          아래 예) personal_choi = PersonalInfo('CK Choi', 25)




# class definition starts with 'class' keyword

# class name starts with the CAPITAL LETTER usually

class PersonalInfo:

    

    # Class attribute

    nationality = "Korean"

    

    # Initalizer, Instance attributes

    def __init__(self, name, age):

        self.name = name

        self.age = age

        

    # instance method 1

    def getPersonalInfo(self):

        print("Name:", self.name)

        print("Age:", self.age)

        

    # instance method 2

    def ageGroup(self):

        if self.age < 30:

            return "under 30"

        else:

            return "over 30"

        

    # instance method 3

    def FirstName(self):

        print(self.name.split(' ')[0])

    

    # instance method 4

    def LastName(self):

        print(self.name.split(' ')[1])

 




아래 코드는 클래스 생성 시점에 메모리에 같이 저장이 되고, 클래스 전체에서 공유하는 속성인 클래스 속성(class attribute) 값을 조회한 결과입니다. '클래스이름.속성이름'  의 형태로 조회합니다. 



# get class attribute

PersonalInfo.nationality

[Out]:'Korean'

 




아래의 코드는 클래스를 상세화/구체화하여 인스턴스 객체를 생성한 예입니다. 인스턴스 객체의 속성과 메소드는 인스턴스 객체를 생성하는 시점에 메모리에 저장이 됩니다.  


인스턴스 객체를 생성할 때마다 __init__(self) 의 마법 메소드(magic method)가 속성 값을 초기화(initialization) 해줍니다. 인스턴스 속성은 '인스턴스 객체 이름'에 점('.')을 찍고 뒤에 '속성 이름'을 써주면 조회할 수 있습니다.  

    아래 예) personal_choi.name


인스턴스 메소드 호출은 인스턴스 객체 이름에 점('.')을 찍고 뒤에 '메소드 이름()'을 써주면 됩니다. 

    아래 예) personal_choi.getPersonalInfo()


인스턴스 객체 1 (instance object 1)

인스턴스 객체 2 (instance object 2)


# instance

personal_choi = PersonalInfo('CK Choi', 25)


# get instance attribute

personal_choi.name

[Out]: 'CK Choi'


# instance method 1

personal_choi.getPersonalInfo()

[Out]:
Name: CK Choi
Age: 25


# instance method 2

personal_choi.ageGroup()

[Out]: 'under 30'


# instance method 3

personal_choi.FirstName()

[Out]: CK


# instance method 4

personal_choi.LastName()

[Out]: Choi



# instance

personal_park = PersonalInfo('SJ Park', 33)


# get instance attribute

personal_park.name

[Out]: 'SJ Park'

# instance method 1 personal_choi.getPersonalInfo()

[Out]: 
Name: SJ Park
Age: 33


# instance method 2

personal_park.ageGroup()

[Out]: 'over 30'

# instance method 3

personal_park.FirstName()

[Out]: SJ


# instance method 4

personal_park.LastName()

[Out]: Park





  4. 클래스 상속이란 무엇인가? 





부모가 자식에게 재산을 상속하듯이, 클래스도 클래스가 다른 클래스에게 상속을 해줄 수 있습니다. 상속을 해주는 클래스를 부모 클래스(Parent Class) 혹은 기반 클래스(Base Class) 라고 하며, 상속을 받는 클래스를 자식 클래스(Child Class) 혹은 파생 클래스(Derived Class)라고 합니다. 도형으로 표기할 때는 바로 위 그림의 예시처럼 '자식 클래스'에서 시작해서 '부모 클래스'로 향하는 화살표를 그려줍니다. 


부모 클래스를 생성한 후에 자식 클래스 이름 끝의 괄호() 안에 부모 클래스의 이름을 적어주면 자식 클래스가 부모 클래스의 모든 데이터 속성과 메소드를 유산으로 상속받아 부모 클래스처럼 역할을 할 수가 있습니다. 

    위의 그림 예) class ChildClass(ParentClass): 

                             pass



위의 '3. 클래스는 어떻게 만드는가?'에서 들었던 예제 클래스 PersonalInfo 를 부모 클래스로 하고, 이를 상속받은 자식 클래스를 class ContactInfo(PersonalInfo):  로 아래에 만들어보겠습니다. 부모 클래스에서 상속받은 데이터 속성, 메소드 외에 def getContactInfo(self, cellphone, city): 로 인스턴스 메소드를 추가로 정의해주었습니다. 



# Child(derived) class (inherits from PersonalInfo() parent(base) class)

class ContactInfo(PersonalInfo):

    def getContactInfo(self, cellphone, city):

        print("Name:", self.name)

        print("Age:", self.age)

        print("Celluar Phone:", cellphone)

        print("City:", city)

 



아래에는 contact_lee = ContactInfo('SH Lee', 41) 으로 위의 자식 클래스를 상세화한 contact_lee 라는 이름의 인스턴스 객체를 만들었습니다. 아래에 보시다시피 getPersonalInfo(), ageGroup(), FirstName(), LastName() 등의 부모 클래스에서 정의했던 인스턴스 메소드를 자식 클래스로 부터 생성한 인스턴스에서도 동일하게 사용할 수 있음을 알 수 있습니다. 



contact_lee = ContactInfo('SH Lee', 41)


# instance method from Parent class

contact_lee.getPersonalInfo()

[Out]:

Name: SH Lee Age: 41


# instance method from Parent class

contact_lee.ageGroup()

[Out]: 'over 30'


# instance method from Parent class

contact_lee.FirstName()

[Out]: SH


# instance method from Parent class

contact_lee.LastName()

[Out]: Lee


# -- instance method from Child class

contact_lee.getContactInfo('011-1234-5678', 'Seoul')

[Out]: 
Name: SH Lee
Age: 41
Celluar Phone: 011-1234-5678
City: Seoul





  5. 클래스와 함수의 차이점은 무엇인가


코드의 재사용성(reusability) 측면에서는 클래스와 함수가 유사한 측면도 있습니다만, 클래스와 함수는 엄연히 다릅니다. 클래스의 이해를 돕기 위해 마지막으로 한번 더 정리하는 차원에서 클래스와 함수의 차이점을 비교해보자면요, 



  • 클래스(class)는 같은 목적과 기능을 위해 '데이터 속성(변수)'과 '기능(함수)'를 결합해 놓은 집합체/그룹으로서, 객체 지향 프로그래밍에서 인스턴스 객체를 생성하는데 사용이 됩니다. 
  • vs. 함수(function)는 특정 기능/과업을 수행하는 코드 블록입니다. (A function is a unit of code devoted to carrying out a specific task)

클래스(class)가 함수(function) 보다 더 광범위한 개념이며, 함수는 클래스의 부분집합입니다. 


많은 도움이 되었기를 바랍니다.

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



[Reference]

1. '뇌를 자극하는 파이썬3', 박상현 지음, 한빛미디어

2. Object-Oriented Programming in Python 3, by Real Python

3. Object-Oriented Programming, Wikipedia




728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Jupyter Notebook을 사용하는데 있어 자주 쓰는 것은 아니지만 한번 쓰려고 하면 방법을 찾으려고 하면 또 시간을 빼앗기곤 하는, 그래서 어디에 메모해두었다가 필요할 때 꺼내쓰기에 아기자기한 팁들을 모아보았습니다. 

 

(1) Jupyter Notebook cell 너비 설정하기

(2) Jupyter Notebook에서 DataFrame 칼럼 최대 너비 설정하기

(3) Jupyter Notebook에서 DataFrame 내 텍스트를 왼쪽으로 정렬하기

(4) Jupyter Notebook에서 DataFrame 소수점 자리수 설정하기

(5) Jupyter Notebook에서 matplotlib plot 기본 옵션 설정하기 (figure size, line width, color, grid)

(6) Jupyter Notebook에서 출력하는 행의 최대개수 설정하기 (number of max rows) 

 

 

 (1) Jupyter Notebook cell 너비 설정하기 (setting cell width in Jupyter Notebook)

 

아래 코드의 부분의 숫자를 바꾸어주면 됩니다.  

 

 

from IPython.core.display import display, HTML

 

display(HTML("<style>.container { width: 50% !important; }</style>"))

 

 

 

 

 

 (2) Jupyter Notebook에서 DataFrame 칼럼 최대 너비 설정하기 

     (setting the max-width of DataFrame's column in Jupyter Notebook)

 

 

 

import pandas as pd

pd.set_option('display.max.colwidth', 10)

 

df = pd.DataFrame({'a': [100000000.0123, 20000000.54321], 

                  'b': ['abcdefghijklmnop', 'qrstuvwxyz']})

 

df

 

 
 
Out[2]:
  a b
0 1.0000... abcdef...
1 2.0000... qrstuv...

 

 
 
 
pd.set_option('display.max.colwidth', 50)
 
df
 
Out[3]:
 
 
  a b
0 1.000000e+08 abcdefghijklmnop
1 2.000000e+07 qrstuvwxyz
 

 

 

 

 

 

 (3) Jupyter Notebook에서 DataFrame 내 텍스트를 왼쪽으로 정렬하기 

     (align text of pandas DataFrame to left in Jupyter Notebook)

 

 

dfStyler = df.style.set_properties(**{'text-align': 'left'})

dfStyler.set_table_styles([dict(selector='th', 

                                props=[('text-align', 'left')])])

 

 
 
Out[4]:
  a b
0 1e+08 abcdefghijklmnop
1 2e+07 qrstuvwxyz

 

 

 

 

 

 (4) Jupyter Notebook에서 DataFrame 소수점 자리수 설정하기

     (setting the decimal point format of pandas DataFrame in Jupyter Notebook)

 

아래에 예시로 지수형 표기를 숫자형 표기로 바꾸고, 소수점 2째자리까지만 나타내도록 숫자 표기 포맷을 설정해보겠습니다. 

 

 

import pandas as pd

pd.options.display.float_format = '{:.2f}'.format

 

 

df

 
 
Out[6]:
  a b
0 100000000.01 abcdefghijklmnop
1 20000000.54 qrstuvwxyz

 

 

 

 

 

 (5) Jupyter Notebook에서 matplotlib plot 기본 옵션 설정하기 

    (setting figure size, line width, color, grid of matplotlib plot in Jupyter Notebook)

 

matplotlib.pyplot 의 plt.rcParams[] 를 사용하여 그래프 크기, 선 너비, 선 색깔, 그리드 포함 여부 등을 설정할 수 있습니다. 

 

 

# matplotlib setting

import matplotlib.pylab as plt

%matplotlib inline

 

plt.rcParams["figure.figsize"] = (6, 5)

plt.rcParams["lines.linewidth"] = 2

plt.rcParams["lines.color"] = 'r'

plt.rcParams["axes.grid"] = True

 

# simple plot

x = [1, 2, 3, 4, 5]

y = [2, 3.5, 5, 8, 9]

 

plt.plot(x, y)

plt.show()

 

 

 

 

 

 (6) Jupyter Notebook에서 출력하는 최대 행의 개수 설정하기 (number of max rows)

 

Jupyter Notebook 셀에서 DataFrame 인쇄 시에 기본 설정은 행의 개수가 많을 경우 중간 부분이 점선으로 처리 ("...")되어 건너뛰고, 처음 5개행과 마지막 5개 행만 선별해서 보여줍니다.   

 

 

# if there are many rows, JN does not print all rows

import pandas as pd
import numpy as np

 

df = pd.DataFrame(np.arange(200).reshape(100, 2))
df
 

 

 

 

그런데, 필요에 따라서는 전체 행을 프린트해서 눈으로 확인해봐야할 때도 있습니다. 이럴 경우 Jupyter Notebook에서 출력하는 최대 행의 개수 (the number of max rows in Jupyter Notebook) 를 설정할 수 있습니다. 위의 예에서 5번째 행부터 점선으로 처리되어 건너뛰고 안보여지던 행이, pd.set_option('display.max_rows', 100) 으로 최대 인쇄되는 행의 개수를 100개로 늘려서 설정하니 이번에는 100개 행이 전부 다 인쇄되어 볼 수 있습니다. 

 

 

# setting the number of maximum rows in Jupyter Notebook

import pandas as pd

pd.set_option('display.max_rows', 100)

df
 

 

 

 (7) Jupyter Notebook에서 출력하는 최대 열의 개수 설정하기 (number of max columns)

 

Jupyter Notebook 셀에서 DataFrame 인쇄 시에 기본 설정은 열의 개수가 20개를 넘어가면 중간 부분이 점선으로 처리 ("...")되어 건너뛰고, 나머지 20개만 출력을 해줍니다.  아래의 화면 캡쳐 예시처럼 중간 열 부분의 결과가 "..." 으로 가려져있어서 확인할 수가 없습니다. 

 

 

이럴 경우에 pandas.set_option('display.max.columns', col_num) 옵션을 사용하여 화면에 보여주는 최대 열의 개수 (maximum number of columns)"를 옵션으로 설정해줄 수 있습니다.   위에서는 ... 으로 처리되었던 열10 ~ 열12 가 아래에서는 제대로 jupyter notebook에 출력되었네요!

 

 

# setting the maximum number of columns in jupyter notebook display

import pandas as pd

 

pd.set_option('display.max.columns', 50) # set the maximum number whatever you want
 

 

 

많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~

'를 꾹 눌러주세요. :-)

 

 

728x90
반응형
Posted by Rfriend
,

Python은 Jupyter Notebook, R은 RStudio 라고만 알고 있는 분도 계실텐데요, IRKernel을 설치해주면 Jupyter Notebook에서도 R을 사용할 수 있습니다


이번 포스팅에서는 Jupyter Notebook에서 R을 사용할 수 있도록 하는 방법을 소개하겠습니다. 

(MacOS, Anaconda, Python3.6 version 환경)


명령 프롬프트 창(prompt window, terminal) 에서 아래의 절차에 따라서 IRKernel을 설치해주시면 됩니다. 

(RStudion에서 설치를 하려고 하면 에러가 납니다. 명령 프롬프트창/ Terminal에서 진행하기 바랍니다)



  1. Jupyter Notebook 사용할 수 있도록 IRKernel 설치하기



(1) 명령 프롬프트 창(terminal)에서 'R' 을 써주고 엔터 => R을 실행합니다. 



MacBook-Pro:~ ihongdon$

MacBook-Pro:~ ihongdon$ R


R version 3.6.0 (2019-04-26) -- "Planting of a Tree"

Copyright (C) 2019 The R Foundation for Statistical Computing

Platform: x86_64-apple-darwin15.6.0 (64-bit)

 





(2) devtools 패키지를 설치합니다: install.packages('devtools')


'현재 세션에서 사용할 CRAN 미러를 선택해 주세요' 라는 메시지와 함께 콤보 박스 창이 뜨면 서버 아무거나 선택하면 됩니다. 저는 'SEOUL' 선택했습니다. 



>

> install.packages('devtools')

--- 현재 세션에서 사용할 CRAN 미러를 선택해 주세요 ---


SEOUL



경고: 저장소 https://cran.seoul.go.kr/bin/macosx/el-capitan/contrib/3.6에 대한 인덱스에 접근할 수 없습니다:

  URL 'https://cran.seoul.go.kr/bin/macosx/el-capitan/contrib/3.6/PACKAGES'를 열 수 없습니다

소스형태의 패키지 ‘devtools’(들)를 설치합니다.


URL 'https://cran.seoul.go.kr/src/contrib/devtools_2.2.1.tar.gz'을 시도합니다

Content type 'application/x-gzip' length 372273 bytes (363 KB)

==================================================

downloaded 363 KB


* installing *source* package ‘devtools’ ...

** 패키지 ‘devtools’는 성공적으로 압축해제되었고, MD5 sums 이 확인되었습니다

** using staged installation

** R

** inst

** byte-compile and prepare package for lazy loading

** help

*** installing help indices

*** copying figures

** building package indices

** installing vignettes

** testing if installed package can be loaded from temporary location

** testing if installed package can be loaded from final location

** testing if installed package keeps a record of temporary installation path

* DONE (devtools)


다운로드한 소스 패키지들은 다음의 위치에 있습니다

‘/private/var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T/Rtmpg1bePN/downloaded_packages’

>

 




(3) IRkernel 설치: devtools::install_github('IRkernel/IRkernel') 실행합니다. 



>

> devtools::install_github('IRkernel/IRkernel')

Downloading GitHub repo IRkernel/IRkernel@master

'/usr/local/bin/git' clone --depth 1 --no-hardlinks --recurse-submodules https://github.com/jupyter/jupyter_kernel_test.git /var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T//Rtmpg1bePN/remotes36921150b621/IRkernel-IRkernel-67592db/tests/testthat/jkt

'/var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T//Rtmpg1bePN/remotes36921150b621/IRkernel-IRkernel-67592db/tests/testthat/jkt'에 복제합니다...

remote: Enumerating objects: 12, done.

remote: Counting objects: 100% (12/12), done.

remote: Compressing objects: 100% (11/11), done.

remote: Total 12 (delta 1), reused 3 (delta 0), pack-reused 0

오브젝트 묶음 푸는 중: 100% (12/12), 완료.

'/usr/local/bin/git' clone --depth 1 --no-hardlinks --recurse-submodules https://github.com/flying-sheep/ndjson-testrunner.git /var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T//Rtmpg1bePN/remotes36921150b621/IRkernel-IRkernel-67592db/tests/testthat/njr

'/var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T//Rtmpg1bePN/remotes36921150b621/IRkernel-IRkernel-67592db/tests/testthat/njr'에 복제합니다...

remote: Enumerating objects: 10, done.

remote: Counting objects: 100% (10/10), done.

remote: Compressing objects: 100% (8/8), done.

remote: Total 10 (delta 0), reused 6 (delta 0), pack-reused 0

오브젝트 묶음 푸는 중: 100% (10/10), 완료.

Skipping 1 packages ahead of CRAN: htmltools

   checking for file ‘/private/var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T/Rtmpg1bePN/remotes36921150b621/IRkernel✔  checking for file ‘/private/var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T/Rtmpg1bePN/remotes36921150b621/IRkernel-IRkernel-67592db/DESCRIPTION’

─  preparing ‘IRkernel’:

✔  checking DESCRIPTION meta-information ...

─  checking for LF line-endings in source and make files and shell scripts

─  checking for empty or unneeded directories

   Removed empty directory ‘IRkernel/example-notebooks’

─  building ‘IRkernel_1.0.2.9000.tar.gz’


* installing *source* package ‘IRkernel’ ...

** using staged installation

** R

** inst

** byte-compile and prepare package for lazy loading

** help

*** installing help indices

** building package indices

** testing if installed package can be loaded from temporary location

** testing if installed package can be loaded from final location

** testing if installed package keeps a record of temporary installation path

* DONE (IRkernel)

>

 




(4) IRkernel::installspec()  확인



>

> IRkernel::installspec()

[InstallKernelSpec] Installed kernelspec ir in /Users/ihongdon/Library/Jupyter/kernels/ir

>

 



만약 아래와 같은 메시지가 떴다면 이는 아마도 위의 (1), (2), (3) 절차를 "명령 프롬프트 창(Terminal)"에서 실행한 것이 아니라 "RStudio"에서 실행했기 때문일 것입니다. 


jupyter-client has to be installed but “jupyter kernelspec –version” exited with code 127.


위의 메시지가 떴다면 명령 프롬프트 창(prompt window, Terminal)을 하나 열고 위의 (1), (2), (3) 절차를 실행한 후에 (4)로 확인을 해보세요. 



Windows10 OS를 사용하는 분이라면 PATH에 아래 경로를 추가로 등록해보시기 바랍니다. 


 

 Anaconda\Lib\site-packages\jupyter_client


 C:\Users\Anaconda3\Scripts 



참고로 Windows 10, Windows 8에서 PATH 등록하는 법은 아래와 같습니다. 

[ Windows10 또는 Windows8 에서 PATH 등록 ]


  1. 시스템(제어판)’ 선택
  2. 고급 시스템 설정 링크선택(클릭)
  3. 환경변수선택 —> 시스템 변수 섹션에서 ‘PATH 환경변수선택 —> ‘편집선택 —> PATH 환경변수가 존재하지 않을 경우새로 만들기선택
  4. 시스템 변수 편집 (또는 시스템 변수)’ 창에서 PATH 환경 변수의 값을 지정 —> ‘확인선택 —> 나머지 모두 닫기





  2. Jupyter Notebook에서 R 사용해보기


R kernel 도 잘 설치가 되었으니 Jupyter Notebook에서 R을 사용해보겠습니다.  위의 R이 실행 중인 terminal 에서 'ctrl + z' 를 눌러서 빠져나옵니다. 


$ conda info -e (혹은 conda env list) 로 가상환경 목록을 확인하고, 

$ source activate [가상환경 이름] 으로 특정 가상환경으로 들어갑니다. 

(Windows OS 에서는 activate [가상환경 이름])

$ jupyter notebook 로 jupyter notebook 창을 열어줍니다. 



>

>

[1]+  Stopped                 R

MacBook-Pro:~ ihongdon$

MacBook-Pro:~ ihongdon$ conda info -e

# conda environments:

#

base                  *  /Users/ihongdon/anaconda3

py2.7_tf1.4              /Users/ihongdon/anaconda3/envs/py2.7_tf1.4

py3.5_tf1.4              /Users/ihongdon/anaconda3/envs/py3.5_tf1.4

py3.6_tf2.0              /Users/ihongdon/anaconda3/envs/py3.6_tf2.0


MacBook-Pro:~ ihongdon$

MacBook-Pro:~ ihongdon$

MacBook-Pro:~ ihongdon$ source activate py3.6_tf2.0

(py3.6_tf2.0) MacBook-Pro:~ ihongdon$

(py3.6_tf2.0) MacBook-Pro:~ ihongdon$ jupyter notebook

 




아래처럼 Jupyter Notebook 창이 뜨면 오른쪽 상단의 'New' 메뉴를 클릭하고, 여러 하위 메뉴 중 'R' 선택합니다. 





간단한 예제로 x, y 두개 변수로 구성된 R 데이터프레임을 하나 만들고, ggplot2 로 산점도를 그려보았습니다. 






다음으로 종속변수 y에 대해 설명변수 x를 사용한 선형회귀모형을 적합시켜 보았습니다. 




많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)





728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Windows 환경에서 Anaconda Python 배포판으로 Python을 설치했을 경우에, Anaconda Prompt 를 이용하여 Python x.x 버전의 새로운 가상환경(Virtual Environment)을 만드는 방법을 소개하겠습니다. 

가상환경(Virtual Environment)을 이용하면 Python 버전 간의 의존성을 고려해서 가상의 격리된 환경을 만들어줌으로써 버전이 다름으로 인해 발생할 수 있는 호환이나 충돌 문제를 미연에 방지할 수 있도록 해줍니다. Anaconda Python 배포판에서는 conda command 로 가상환경, Python 패키지 설치를 관리할 수 있습니다. 


Anaconda Navigator에서 UI를 가지고 좀더 쉽게 가상환경을 만들 수도 있기는 한데요, 가끔 보면 Windows OS 노트북 사용하는 분들 중에 Anaconda Navigator 를 실행시켜면 화면으로 뜨는데 5분~10분 정도씩 걸리는 경우도 있더라구요. 그래서 빠르게 바로 실행시킬 수 있는 Anaconda Prompt 를 사용해서 가상환경 만드는 방법을 소개하겠습니다.  

먼저 Windows 실행 버튼을 눌러서 Anaconda Prompt 메뉴를 찾아 실행합니다.  python -V 커맨드로 확인해보니 저는 python 3.5.2 버전을 쓰고 있습니다. Python 2.7 버전으로 새로운 가상환경을 만들어보겠습니다. 

 > python -V



1. Conda 버전 확인 및 Conda Update


conda 를 최신버전으로 업데이트를 해줍니다. 중간에 Proceed ([y]/n)? 질문이 나오면 'y' 를 입력해줍니다. 

conda -V

conda update conda

Proceed ([y]/n)? y



 2. 가상환경 목록 확인 (Check virtual environments list)


 > conda env list

또는 

conda info -e



 3. conda로 가상환경 새로 만들기 (Create a new virtual environment using conda)

> conda create -n [virtual environment name] python=[python version] anaconda

의 형식과 순서대로 입력해줍니다. 저는 새로운 가상환경 이름을 'py_2.7'로 하였고, python 2.7 버전으로 anaconda 배포판을 이용해서 가상환경을 만들어보겠습니다. 

 conda create  -n  py_2.7  python=2.7  anaconda

이렇게 하면 아래처럼 Python 2.7 버전과 호환이 검증된 다른 Python libraries 들이 버전을 맞추어서 자동으로 수십개가 설치가 됩니다. 


중간에 Proceed ([y]/n)? 라고 묻거든 'y' 라고 답해주세요. 


혹시 SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 라는 SSLError 가 발생하면 아래의 "conda config --set ssl_verify false"라는 command를 실행하고 난 후에, 위의 "conda create -n py_2.7 python=2.7 anaconda" 커맨드를 다시 실행시켜 보세요. 

 > conda config --set ssl_verify false

혹은 Anaconda Navigator의 Preference에서 'enable SSL verification' 옵션의 체크박스를 해제해주고 "conda create -n py_2.7 python=2.7 anaconda"를 다시 실행해보기 바랍니다. 


"py_2.7" 이라는 이름의 가상환경이 잘 만들어졌는지 확인해볼까요? (이번에는 "conda env list" 대신에 "conda info -e"를 사용해서 가상환경 목록 확인)

 


 4. 가상환경 활성화 하기 (Activate Virtual Environment)


"activate [virtual environment name]" 형식으로 커맨드를 입력해주면 해당 이름/ Python 버전의 가상환경이 활성화되어서 이용 가능해집니다. 방금 새로 만든 python 2.7 버전으로 설치한 "py_2.7" 이름의 가상환경을 활성화해보겠습니다. 
(참고로, Mac OS에서는 > source activate [virtual_env_name] 으로서, Windows랑 조금 다릅니다.)

 > activate py_2.7


아래 화면 캡쳐해놓은 것처럼 activate py_2.7 을 하고 나면 "(py_2.7) C:\Users\admin>" 과 같이 커서 화면이 바뀝니다. 



 5. IDE (Jupyter Notebook, Spyder, IPython) 실행하기

conda prompt 창에서 커맨드 명령문으로 "py_2.7" 이라는 이름의 가상환경에서 python 2.7 버전을 사용할 수 있게 Jupyter Notebook, Spyder, IPython 등의 IDE 를 실행시킬 수 있습니다. 

5-1. Jupyter Notebook 실행

 (py_2.7) > jupyter notebook 

아래처럼 웹브라우저가 뜨면서 Jupyter Notebook이 실행되면 우측 상단의 'New' 메뉴에서 'Python 2'를 선택해서 새로운 Notebook 화면을 생성합니다.

아래처럼 새로운 Notebook 화면이 뜨면 이름 설정해주고 사용하면 되겠습니다. 탐색적 데이터 분석이나 교육용으로 사용하기에는 Jupyter Notebook이 제격이지요. 

Jupyter Notebook 다 사용하였으면 저장하고, 노트북 홈 화면에서 작업한 파일 shutdown 하구요, conda prompt 창에서 'Ctrl + C' 해주면 jupyter notebook kernel 종료(kernel shutdown)하고 빠져나올 수 있습니다. 


5-2. Spyer 실행

 (py_2.7) > spyder

Python으로 Project별로 Production 하기에는 Spyder나 Pycharm 이 작업하기에 더 편한거 같습니다. 


5-3. IPython 실행

 (py_2.7) > IPython

그냥 가볍고, 깔끔하고, interactive 하게 코딩하고 싶으면 IPython 이용하면 되겠습니다. 



 6. 가상환경 비활성화/ 종료하기 (Deactivate a Virtual Environment)

가상환경을 종료하려면 > deactivate 해줍니다. 

(참고로, MacOS 사용자라면 > conda deactivate 로서, Windows와는 조금 다릅니다)

 (py_2.7) > deactivate

아래 화면 캡쳐한 것처럼 가상환경을 deactivate 해주면 "C:\Users\admin>" 으로 커서가 빠져나옵니다. 



 7. 가상환경 제거 하기 (Delete a Virtual Environment)

특정 Python 버전을 쓰는 프로젝트가 끝나서 더이상 쓸모가 없거나, 오래된 버전이라서 사용하지 않게 된 가상환경을 삭제하려면 > conda env remove -n [virtual environment name]  이라는 커맨드 명령어를 실행시켜줍니다. 

 > conda env remove -n py_2.7

그러면 자동으로 전체 가상환경 내 library 들을 지워주며, 다른 가상환경과는 격리되어 있기 때문에 아무런 영향없이 지워줍니다. 좋지요?! :-)


자동으로 버전 맞춰서 설치되었던 Python libraries 들을 지울건데 정말로 지워도 되냐고 확인 (Proceed ([y]/n)?)하려고 물어보는데요, y 라고 답해주기 바랍니다. 


> conda env list  로 가상환경 목록을 확인해보니 'py_2.7' 이라는 이름의 python 2.7 버전의 가상환경이 안보이네요. 잘 제거된거 맞네요. 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)


728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Windows10 OS 에서

(1) Python으로 Postgresql, Greenplum DB connect 하고 Query 결과 가져오는 방법

(2) Python으로 MySQL DB connect 하고 Query 결과 가져오는 방법

(3) Python으로 IBM DB2 DB connect 하고 Query 결과 가져오는 방법

(4) Python으로 Presto, Hive DB connect 하고 Query 결과 가져오는 방법

을 소개하겠습니다.

 

 (1) Python으로 Postgresql, Greenplum DB connect 하고 Query 결과 가져오는 방법

먼저, 명령 프롬프트 창에서 psycopg2 라이브러리를 설치해줍니다.

 $ pip install psycopg2

Spyder 등의 Python IDE에서 PostgreSQL, Greenplum DB에 접속하고 query를 실행하여 결과를 pandas DataFrame으로 받아와서 저장하는 사용자 정의함수를 정의합니다.

( * Reference : PostgreSQL Python: Connect to PostgreSQL Database Server )

 

[ UDF of connecting to Postgresql, GPDB & Getting query result as a DataFrame ]

def postgresql_query(query): 

    import psycopg2 as pg
    import pandas as pd

    # Postgresql, Greenplum DB Connect
    connection_string = "postgresql://{user}:{password}@{host}/{db}".\
        format(user='gpadmin',  # put your info
                 password='changeme', 
                 host='localhost', 
                 db='gpadmin')

    conn = pg.connect(connection_string)

    cursor = conn.cursor()

    #conn.autocommit = True

    # execute a query and get it as a pandas' DataFrame
    cursor.execute(query)
    col_names = [desc[0] for desc in cursor.description]
    result = pd.DataFrame(cursor.fetchall(), columns=col_names)

   cursor.close()

   conn.close()

    return result


 

아래는 Query를 실행해서 결과를 가져오는 간단한 예시입니다.

query = """
    SELECT * FROM mytable WHERE grp == 'A' LIMIT 100;

    """

postgresql_query(query)grp_A = postgresql_query(query)

 

 

 (2) Python으로 MySQL DB connect 하고 Query 결과 가져오는 방법

먼저, 명령 프롬프트 창에서 mysql 라이브러리를 설치해줍니다.

$ pip install mysql


다음으로 MySQL DB에 접속하고 query를 실행시켜서 결과를 DataFrame으로 가져오는 사용자 정의함수를 정의합니다.

( * Reference : Connecting to MySQL Using Connector/Python )


def mysql_query(query):

    import mysql.connector

    import pandas as pd


    cnx = mysql.connector.connect(user='userid',

                                             password='changeme',

                                             host='12.34.567.890',

                                             database='mydb')

 

    cursor = cnx.cursor()

 

     # execute a query and get it as a pandas' DataFrame
     cursor.execute(query)
     col_names = [desc[0] for desc in cursor.description]
     result = pd.DataFrame(cursor.fetchall(), columns=col_names)

 

    cursor.close()

    cnx.close()

 

    return result

 


위에서 정의한 사용자 정의함수를 사용하여 MySQL DB에 접속하고, Query로 조회한 결과를 result 라는 이름의 DataFrame으로 저장하는 예시입니다.

 

query = """

    SELECT * FROM mydb WHERE age >= 20 ORDER BY age;

    """

 

result = mysql_query(query)

 

 

 (3) Python으로 IBM DB2 DB connect 하고 Query 결과 가져오는 방법

먼저, 명령 프롬프트 창에서 ibm_db_dbi 라이브러리를 설치해줍니다.

$ pip install ibm_db_dbi


다음으로 DB2에 접속해서 Query를 실행하고, 결과를 pandas DataFrame으로 가져오는 사용자 정의함수를 정의합니다.

( * Reference : Connecting to an IBM database server in Python)


def db2_query(query):
    

    import ibm_db_dbi as db

    import pandas as pd

    conn = db.connect('DATABASE=mydb;' 
                             'HOSTNAME=12.34.567.890;' 
                             'PORT=50000;' 
                             'PROTOCOL=TCPIP;' 
                             'UID = secret;' 
                             'PWD= changeme;', '', ' ')

     cursor = conn.cursor()
     cursor.execute(query)
     col_names = [desc[0] for desc in cursor.description]

     result = pd.DataFrame(cursor.fetchall(), columns=col_names)

     cursor.close()
     conn.close()
 
     return result

 

 

Python에서 Query를 실행시켜서 결과를 pandas DataFrame을 가져오는 예시는 아래와 같습니다.

query = """

    SELECT school_nm, count(*) as student_cnt

    FROM school

    WHERE school_nm LIKE 'seoul%';

    """

 

school = db2_query(query)

 

 

 (4) Python으로 Presto, Hive DB connect 하고 Query 결과 가져오는 방법

먼저 명령 프롬프트 창에서 pyhive 라이브러리를 설치해줍니다.

$ pip install pyhive


Presto 혹은 Hive에 접속하고 Query를 실행해서 결과를 pandas DataFrame으로 가져오는 사용자 정의함수를 정의합니다.

( * Reference : PyHive is a collection of Python DB-API and SQLAlchemy interfaces for Presto and Hive  )

 


def presto_query(query):

     from pyhive import presto
     import pandas as pd

     cursor = presto.connect('12.34.567.890').cursor()
    

     # execute a query and get a result as a DataFrame

     cursor.execute(query)
     col_names = [ desc[0] for desc in cursor.description ]
     result = pd.DataFrame(cursor.fetchall(), columns=col_names)

     cursor.close()
 
     return result

 


Python에서 위의 사용자 정의 함수를 사용하여 query를 실행시키고 결과를 DataFrame으로 가져오는 예제입니다.

 

query = """

    WITH

        t1 AS (SELECT a, MAX(b) AS b FROM x GROUP BY a),

        t2 AS (SELECT a, AVG(d) AS d FROM y GROUP BY a)

    SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.a = t2.a;

    """

result = presto_query(query)

 

 

혹시 pip install 하는 단계에서 'error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/' 와 같은 에러가 나면 안내에 나와있는 사이트에 가서 Microsoft Visual C++ 을 다운받아 설치하시기 바랍니다.

 

많은 도움이 되었기를 바랍니다.

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 맥 OS 컴퓨터에 시각화 소프트웨어인 Graphviz, pygraphviz 를 설치하고 파이썬에서 실행을 했을 때 

ValueError: Program dot not found in path

라는 에러 메시지가 발생했을 때 대처방안을 소개하겠습니다.  맥북 노트북에서는 아무런 문제 없이 설치해서 graphviz 를 썼는데요, 맥북 컴퓨터에서는 설치까지는 잘 되었는데 사용하려고 하니 이 문제가 발생해서 두시간 정도 구글링 하면서 삽질을 했습니다. ㅜ_ㅜ  이거 pygraphviz의 버그인거 같습니다. 저처럼 삽질하면서 아까운 시간 버리지 마시길 바래요. 

(참고로 python 2.7 사용 중입니다.)


(1) 'dot' path 확인하기

(2) pygraphviz패키지의 agraph.py 파일에서 runprog 경로에 (1)에서 찾은 경로로 수정해주기



  (1) 'dot' path 확인하기 : $ which dot


터미널 창을 하나 띄우시고 아래처럼 '$ which dot' 을 입력하면 dot program이 설치되어 있는 경로(path)를 찾을 수 있습니다.  제거는 /usr/local/bin/dot 에 설치가 되어 있네요. 



abc:~ ddd$ which dot

/usr/local/bin/dot


abc:~ ddd$ dot -V

dot - graphviz version 2.40.1 (20161225.0304)

 




  (2) pygraphviz 패키지의 agraph.py 파일에서 runprog 경로에 (1)에서 찾은 경로로 수정해주기


'Spotlight 검색'(command + spacebar) 창에서 'agraph.py'라는 키워드로 검색하면 아래와 같이 pygraphviz 패키지의 agraph.py 파일을 찾을 수 있습니다.  agraph.py 파이썬 프로그램 파일을 열어보세요. 





다음에 'command + F'를 눌러서 검색할 수 있는 창이 나오면 'runprog' 키워드로 검색을 한 후에 -> runprog = self._which(prog) 가 있는 라인을 찾아보세요. 제거에 설치된거는 1,289번째 라인에 있네요. 


(1) 번에서 터미널 창을 뜨워놓고 '$ which dot' 명령어를 실행해서 dot 프로그램이 설치된 경로(제거는 /usr/local/bin/dot )를 찾았는데요, 그 경로를 복사해다가 아래처럼 수정(제 맥 컴퓨터의 경우  runprog = "/usr/local/bin/dot"  로 수정함)을 해주시기 바랍니다. 



수정 전 (Before)

수정 후 (After) 

 def _get_prog(self, prog):

        # private: get path of graphviz program

        progs = ['neato', 'dot', 'twopi', 'circo',
               'fdp', 'nop',
 'wc', 'acyclic', 'gvpr',
               'gvcolor', 'ccomps', 
'sccmap',
               'tred', 
'sfdp']

        if prog not in progs:

            raise ValueError("Program %s is not
              one of: %s." % 
(prog, ', '.join(progs)))


        try: 

         runprog = self._which(prog)

    

        except:

            raise ValueError("Program %s not
                            found in path." % prog)


        return runprog 

def _get_prog(self, prog):

        # private: get path of graphviz program

        progs = ['neato', 'dot', 'twopi', 'circo',
                 'fdp', 'nop', 
'wc', 'acyclic', 'gvpr',
                 'gvcolor', 'ccomps', 
'sccmap',
                 'tred', 
'sfdp']

        if prog not in progs:

            raise ValueError("Program %s is not
               one of: %s." %
(prog, ', '.join(progs)))


        try:  

          runprog = "/usr/local/bin/dot"

    

        except:

            raise ValueError("Program %s not
                             found in path." % prog)


        return runprog  





수정 후에 저장하고 agraph.py 파이썬 프로그램 파일을 닫은 후에 pygrahpviz 써서 Graphviz 로 네트워크 다이어그램을 시각화하니 잘 되네요. 


많은 도움이 되었기를 바랍니다. 

728x90
반응형
Posted by Rfriend
,

Graphviz AT&T Bell Labs에서 만든 오픈소스 시각화 소프트웨어입니다. Graphviz 구조화된 정보를 추상화된 그래프나 네트워크 형태의 다이어그램으로 제시 해줍니다. 가령, 기계학습의 Decision Tree 학습 결과를 Tree 형태로 시각화 한다든지, Process Mining 통해 찾은 workflow 방향성 있는 네트워크 형태로 시각화 Graphviz 사용할 있습니다. 




PyGraphviz 는 Python으로 Graphviz 소프트웨어를 사용할 수 있게 인터페이스를 해주는 Python 패키지입니다. PyGraphviz를 사용하여 Graphviz 그래프의 데이터 구조와 배열 알고리즘에 접근하여 그래프를 생성, 편집, 읽기, 쓰기, 그리기 등을 할 수 있습니다. 



Python으로 Graphviz를 사용하려면 (a) 먼저 Graphviz S/W를 설치하고, (b) 다음으로 PyGraphviz를 설치해야 합니다.  만약 순서가 바뀌어서 Graphviz 소프트웨어를 설치하지 않은 상태에서 PyGraphviz를 설치하려고 하면 Graphviz를 먼저 설치하라는 에러 메시지가 뜰 겁니다. 순서가 중요합니다! 


  Your Graphviz installation could not be found.

  

          1) You don't have Graphviz installed:

             Install Graphviz (http://graphviz.org) 




이번 포스팅에서는 


(1) Mac OS High Sierra Graphviz 소프트웨어 설치하기

(2) Python 2.7 PyGraphviz library 설치하기

(3) Graphviz와 PyGraphviz를 사용하여 Decision Tree 시각화 해보기


에 대해서 소개하겠습니다. 



  (1) Mac OS High Sierra  Graphviz 소프트웨어 설치하기


(참고로, 저는 Mac OS High Sierra version 10.13.6을 사용하고 있습니다.)


(1-1) Homebrew 를 설치합니다. 

Homebrew는 애플 Mac OS 에서 소프트웨어 패키지를 설치를 간소화해주는 소프트웨어 패키지 관리 오픈소스 툴입니다. 터미널을 하나 열고 아래의 코드를 복사해서 실행하면 됩니다. 


$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null



ihongdon-ui-MacBook-Pro:~ ihongdon$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following existing directories will be made group writable:
/usr/local/bin
/usr/local/include
/usr/local/lib
/usr/local/share
/usr/local/lib/pkgconfig
/usr/local/share/info
/usr/local/share/man
/usr/local/share/man/man1
/usr/local/share/man/man3
/usr/local/share/man/man5
/usr/local/share/man/man7
==> The following existing directories will have their owner set to ihongdon:
/usr/local/bin
/usr/local/include
/usr/local/lib
/usr/local/share
/usr/local/lib/pkgconfig
/usr/local/share/info
/usr/local/share/man
/usr/local/share/man/man1
/usr/local/share/man/man3
/usr/local/share/man/man5
/usr/local/share/man/man7
==> The following existing directories will have their group set to admin:
/usr/local/bin
/usr/local/include
/usr/local/lib
/usr/local/share
/usr/local/lib/pkgconfig
/usr/local/share/info
/usr/local/share/man
/usr/local/share/man/man1
/usr/local/share/man/man3
/usr/local/share/man/man5
/usr/local/share/man/man7
==> The following new directories will be created:
/usr/local/Cellar
/usr/local/Homebrew
/usr/local/Frameworks
/usr/local/etc
/usr/local/opt
/usr/local/sbin
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/var
==> /usr/bin/sudo /bin/chmod u+rwx /usr/local/bin /usr/local/include /usr/local/lib /usr/local/share /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man /usr/local/share/man/man1 /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7
Password:
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/bin /usr/local/include /usr/local/lib /usr/local/share /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man /usr/local/share/man/man1 /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7
==> /usr/bin/sudo /usr/sbin/chown ihongdon /usr/local/bin /usr/local/include /usr/local/lib /usr/local/share /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man /usr/local/share/man/man1 /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/bin /usr/local/include /usr/local/lib /usr/local/share /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man /usr/local/share/man/man1 /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7
==> /usr/bin/sudo /bin/mkdir -p /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/etc /usr/local/opt /usr/local/sbin /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/etc /usr/local/opt /usr/local/sbin /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
==> /usr/bin/sudo /bin/chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
==> /usr/bin/sudo /usr/sbin/chown ihongdon /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/etc /usr/local/opt /usr/local/sbin /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/etc /usr/local/opt /usr/local/sbin /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
==> /usr/bin/sudo /bin/mkdir -p /Users/ihongdon/Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Users/ihongdon/Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown ihongdon /Users/ihongdon/Library/Caches/Homebrew
==> /usr/bin/sudo /bin/mkdir -p /Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown ihongdon /Library/Caches/Homebrew
==> Downloading and installing Homebrew...
HEAD is now at 1c7c876f3 Merge pull request #4736 from scpeters/bottle_json_local_filename
==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
https://github.com/Homebrew/brew#donations
==> Tapping homebrew/core
ihongdon-ui-MacBook-Pro:~ ihongdon$
ihongdon-ui-MacBook-Pro:~ ihongdon$

 




(1-2) Graphviz를 설치합니다.


Homebrew를 설치하였으면,이제 아래의 Homebrew 코드를 터미널에서 실행하여 Graphviz를 설치해줍니다.


$ brew install graphviz




ihongdon-ui-MacBook-Pro:~ ihongdon$
ihongdon-ui-MacBook-Pro:~ ihongdon$ brew install graphviz
==> Installing dependencies for graphviz: libtool, libpng, freetype, fontconfig, jpeg, libtiff, webp, gd
==> Installing graphviz dependency: libtool
==> Downloading https://homebrew.bintray.com/bottles/libtool-2.4.6_1.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libtool--2.4.6_1.high_sierra.bottle.tar.gz
==> Caveats
In order to prevent conflicts with Apple's own libtool we have prepended a "g"
so, you have instead: glibtool and glibtoolize.
==> Summary
🍺 /usr/local/Cellar/libtool/2.4.6_1: 71 files, 3.7MB
==> Installing graphviz dependency: libpng
==> Downloading https://homebrew.bintray.com/bottles/libpng-1.6.35.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libpng--1.6.35.high_sierra.bottle.tar.gz
🍺 /usr/local/Cellar/libpng/1.6.35: 26 files, 1.2MB
==> Installing graphviz dependency: freetype
==> Downloading https://homebrew.bintray.com/bottles/freetype-2.9.1.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring freetype--2.9.1.high_sierra.bottle.tar.gz
🍺 /usr/local/Cellar/freetype/2.9.1: 60 files, 2.6MB
==> Installing graphviz dependency: fontconfig
==> Downloading https://homebrew.bintray.com/bottles/fontconfig-2.13.0.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring fontconfig--2.13.0.high_sierra.bottle.tar.gz
==> Regenerating font cache, this may take a while
==> /usr/local/Cellar/fontconfig/2.13.0/bin/fc-cache -frv
🍺 /usr/local/Cellar/fontconfig/2.13.0: 511 files, 3.2MB
==> Installing graphviz dependency: jpeg
==> Downloading https://homebrew.bintray.com/bottles/jpeg-9c.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring jpeg--9c.high_sierra.bottle.tar.gz
🍺 /usr/local/Cellar/jpeg/9c: 21 files, 724.5KB
==> Installing graphviz dependency: libtiff
==> Downloading https://homebrew.bintray.com/bottles/libtiff-4.0.9_4.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libtiff--4.0.9_4.high_sierra.bottle.tar.gz
🍺 /usr/local/Cellar/libtiff/4.0.9_4: 246 files, 3.5MB
==> Installing graphviz dependency: webp
==> Downloading https://homebrew.bintray.com/bottles/webp-1.0.0.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring webp--1.0.0.high_sierra.bottle.tar.gz
🍺 /usr/local/Cellar/webp/1.0.0: 38 files, 2MB
==> Installing graphviz dependency: gd
==> Downloading https://homebrew.bintray.com/bottles/gd-2.2.5.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring gd--2.2.5.high_sierra.bottle.tar.gz
🍺 /usr/local/Cellar/gd/2.2.5: 35 files, 1.1MB
==> Installing graphviz
==> Downloading https://homebrew.bintray.com/bottles/graphviz-2.40.1.high_sierra.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring graphviz--2.40.1.high_sierra.bottle.1.tar.gz
🍺 /usr/local/Cellar/graphviz/2.40.1: 500 files, 11.2MB
==> Caveats
==> libtool
In order to prevent conflicts with Apple's own libtool we have prepended a "g"
so, you have instead: glibtool and glibtoolize.
ihongdon-ui-MacBook-Pro:~ ihongdon$
ihongdon-ui-MacBook-Pro:~ ihongdon$

 





  (2) Python 2.7 PyGraphviz library 설치하기



PyGraphviz는 Python 3.x 버전, 그리고 Python 2.7 버전에서 사용할 수 있습니다. 이번 포스팅에서는 Python 2.7 버전에 PyGraphviz 패키지를 설치해보겠습니다. 


conda env list로 가상환경 리스트를 확인하고, source activate 로 Python2.7 버전의 가상환경을 활성화시킨 후에, pip install --upgrade pip 로 pip 버전 업그레이드 한 후에, easy_install pygraphviz 로 PyGraphviz를 설치하였습니다. 


왜 그런지 이유는 모르겠으나 pip install pygraphviz 로 설치하려고 하니 설치가 되다가 막판에 에러가 났습니다. 

pip install git://github.com/pygraphviz/pygraphviz.git 도 시도를 해봤는데 역시 에러가 났습니다. 

다행히 easy_install pygrapviz 로 설치가 되네요. 




ihongdon-ui-MacBook-Pro:~ ihongdon$ conda env list

# conda environments:

#

base                  *  /Users/ihongdon/anaconda3

py2.7_tf1.4              /Users/ihongdon/anaconda3/envs/py2.7_tf1.4

py3.5_tf1.4              /Users/ihongdon/anaconda3/envs/py3.5_tf1.4

ihongdon-ui-MacBook-Pro:~ ihongdon$ 

ihongdon-ui-MacBook-Pro:~ ihongdon$ source activate py2.7_tf1.4

(py2.7_tf1.4) ihongdon-ui-MacBook-Pro:~ ihongdon$ pip install --upgrade pip

Requirement already up-to-date: pip in ./anaconda3/envs/py2.7_tf1.4/lib/python2.7/site-packages (18.0)

(py2.7_tf1.4) ihongdon-ui-MacBook-Pro:~ ihongdon$ 

(py2.7_tf1.4) ihongdon-ui-MacBook-Pro:~ ihongdon$ 

(py2.7_tf1.4) ihongdon-ui-MacBook-Pro:~ ihongdon$ easy_install pygraphviz

Searching for pygraphviz

Reading https://pypi.python.org/simple/pygraphviz/

Downloading https://files.pythonhosted.org/packages/87/5e/40efbb2d02ee9d0282f6c8b9e477f6444a025a7ecf8cc0b15fe87a288708

/pygraphviz-1.4rc1.zip#sha256=e0b3a7f1d9203f9748b94e8365656755201966b562e53fd6424bed89e98fdc4e

Best match: pygraphviz 1.4rc1

Processing pygraphviz-1.4rc1.zip

Writing /var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T/easy_install-U3TQDK/pygraphviz-1.4rc1/setup.cfg

Running pygraphviz-1.4rc1/setup.py -q bdist_egg --dist-dir /var/folders/6q/mtq6ftrj6_z4txn_zsxcfyxc0000gn/T/easy_install-U3TQDK/pygraphviz-1.4rc1/egg-dist-tmp-wc0yf4

warning: no previously-included files matching '*~' found anywhere in distribution

warning: no previously-included files matching '*.pyc' found anywhere in distribution

warning: no previously-included files matching '.svn' found anywhere in distribution

no previously-included directories found matching 'doc/build'

pygraphviz/graphviz_wrap.c:3354:12: warning: incompatible pointer to integer conversion returning 'Agsym_t *' (aka 'struct Agsym_s *') from a function with result type 'int' [-Wint-conversion]

    return agattr(g, kind, name, val);

           ^~~~~~~~~~~~~~~~~~~~~~~~~~

pygraphviz/graphviz_wrap.c:3438:7: warning: unused variable 'fd1' [-Wunused-variable]

  int fd1 ;

      ^

pygraphviz/graphviz_wrap.c:3439:13: warning: unused variable 'mode_obj1' [-Wunused-variable]

  PyObject *mode_obj1 ;

            ^

pygraphviz/graphviz_wrap.c:3440:13: warning: unused variable 'mode_byte_obj1' [-Wunused-variable]

  PyObject *mode_byte_obj1 ;

            ^

pygraphviz/graphviz_wrap.c:3441:9: warning: unused variable 'mode1' [-Wunused-variable]

  char *mode1 ;

        ^

pygraphviz/graphviz_wrap.c:3509:7: warning: unused variable 'fd2' [-Wunused-variable]

  int fd2 ;

      ^

pygraphviz/graphviz_wrap.c:3510:13: warning: unused variable 'mode_obj2' [-Wunused-variable]

  PyObject *mode_obj2 ;

            ^

pygraphviz/graphviz_wrap.c:3511:13: warning: unused variable 'mode_byte_obj2' [-Wunused-variable]

  PyObject *mode_byte_obj2 ;

            ^

pygraphviz/graphviz_wrap.c:3512:9: warning: unused variable 'mode2' [-Wunused-variable]

  char *mode2 ;

        ^

9 warnings generated.

zip_safe flag not set; analyzing archive contents...

pygraphviz.graphviz: module references __file__

pygraphviz.release: module references __file__

pygraphviz.tests.test: module references __file__

creating /Users/ihongdon/anaconda3/envs/py2.7_tf1.4/lib/python2.7/site-packages/pygraphviz-1.4rc1-py2.7-macosx-10.6-x86_64.egg

Extracting pygraphviz-1.4rc1-py2.7-macosx-10.6-x86_64.egg to /Users/ihongdon/anaconda3/envs/py2.7_tf1.4/lib/python2.7/site-packages

Adding pygraphviz 1.4rc1 to easy-install.pth file


Installed /Users/ihongdon/anaconda3/envs/py2.7_tf1.4/lib/python2.7/site-packages/pygraphviz-1.4rc1-py2.7-macosx-10.6-x86_64.egg

Processing dependencies for pygraphviz

Finished processing dependencies for pygraphviz

(py2.7_tf1.4) ihongdon-ui-MacBook-Pro:~ ihongdon$ 

(py2.7_tf1.4) ihongdon-ui-MacBook-Pro:~ ihongdon$ 







  (3) Graphviz와 PyGraphviz를 사용하여 Decision Tree 시각화 해보기



이제 Graphviz와 PyGraphviz를 사용해서 Jupyter Notebook 에서 Decision Tree를 시각화해보겠습니다. Iris 데이터셋을 사용해서 Decision Tree로 Iris 종류 분류하는 예제입니다. 







# Common imports

import numpy as np

import os


# To plot pretty figures

%matplotlib inline

import matplotlib

import matplotlib.pyplot as plt


# Where to save the figures

PROJECT_ROOT_DIR = "."

SUB_DIR = "decision_trees"


def image_path(fig_id):

    return os.path.join(PROJECT_ROOT_DIR, "images", SUB_DIR, fig_id)

 


# Iris dataset import

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier


iris = load_iris()
list(iris.keys())
['target_names', 'data', 'target', 'DESCR', 'feature_names']


print(iris.DESCR)
Iris Plants Database
====================

Notes
-----
Data Set Characteristics:
    :Number of Instances: 150 (50 in each of three classes)
    :Number of Attributes: 4 numeric, predictive attributes and the class
    :Attribute Information:
        - sepal length in cm
        - sepal width in cm
        - petal length in cm
        - petal width in cm
        - class:
                - Iris-Setosa
                - Iris-Versicolour
                - Iris-Virginica
    :Summary Statistics:

    ============== ==== ==== ======= ===== ====================
                    Min  Max   Mean    SD   Class Correlation
    ============== ==== ==== ======= ===== ====================
    sepal length:   4.3  7.9   5.84   0.83    0.7826
    sepal width:    2.0  4.4   3.05   0.43   -0.4194
    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)
    petal width:    0.1  2.5   1.20  0.76     0.9565  (high!)
    ============== ==== ==== ======= ===== ====================

    :Missing Attribute Values: None
    :Class Distribution: 33.3% for each of 3 classes.
    :Creator: R.A. Fisher
    :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
    :Date: July, 1988

This is a copy of UCI ML iris datasets.
http://archive.ics.uci.edu/ml/datasets/Iris

The famous Iris database, first used by Sir R.A Fisher

This is perhaps the best known database to be found in the
pattern recognition literature.  Fisher's paper is a classic in the field and
is referenced frequently to this day.  (See Duda & Hart, for example.)  The
data set contains 3 classes of 50 instances each, where each class refers to a
type of iris plant.  One class is linearly separable from the other 2; the
latter are NOT linearly separable from each other.

References
----------
   - Fisher,R.A. "The use of multiple measurements in taxonomic problems"
     Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions to
     Mathematical Statistics" (John Wiley, NY, 1950).
   - Duda,R.O., & Hart,P.E. (1973) Pattern Classification and Scene Analysis.
     (Q327.D83) John Wiley & Sons.  ISBN 0-471-22361-1.  See page 218.
   - Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System
     Structure and Classification Rule for Recognition in Partially Exposed
     Environments".  IEEE Transactions on Pattern Analysis and Machine
     Intelligence, Vol. PAMI-2, No. 1, 67-71.
   - Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule".  IEEE Transactions
     on Information Theory, May 1972, 431-433.
   - See also: 1988 MLC Proceedings, 54-64.  Cheeseman et al"s AUTOCLASS II
     conceptual clustering system finds 3 classes in the data.
   - Many, many more ...

 

 


iris.feature_names

['sepal length (cm)',
 'sepal width (cm)',
 'petal length (cm)',
 'petal width (cm)']


iris.data[:5,]

array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2],
       [ 4.6,  3.1,  1.5,  0.2],
       [ 5. ,  3.6,  1.4,  0.2]])

 





Scikit Learn 의 DecisionTreeClassifier 클래스를 사용하여 iris 분류 모델을 적합시켜 보겠습니다. 





X = iris.data[:, 2:] # petal length and width

y = iris.target

 

# Train the model

tree_clf = DecisionTreeClassifier(max_depth=2)

tree_clf.fit(X, y)






위의 Decision Tree 모형을 export_grapviz() 함수를 사용하여 graphviz의 dot format 파일로 내보내기(export)해보겠습니다. 





# Visualization

from sklearn.tree import export_graphviz


export_graphviz(

        tree_clf,

        out_file=image_path("iris_tree.dot"),

        feature_names=iris.feature_names[2:],

        class_names=iris.target_names,

        rounded=True,

        filled=True

    )

 




위의 export_graphviz() 코드를 실행시키면 ""/Users/ihongdon/images/decision_trees/" 폴더에 iris_tree.dot 파일이 생성됩니다. 이 dot format 파일을 워드나 노트패드를 사용해서 열어보면 아래와 같이 되어있습니다. 



digraph Tree {
node [shape=box, style="filled, rounded", color="black", fontname=helvetica] ;
edge [fontname=helvetica] ;
0 [label="petal width (cm) <= 0.8\ngini = 0.667\nsamples = 150\nvalue = [50, 50, 50]\nclass = setosa", fillcolor="#e5813900"] ;
1 [label="gini = 0.0\nsamples = 50\nvalue = [50, 0, 0]\nclass = setosa", fillcolor="#e58139ff"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="petal width (cm) <= 1.75\ngini = 0.5\nsamples = 100\nvalue = [0, 50, 50]\nclass = versicolor", fillcolor="#39e58100"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
3 [label="gini = 0.168\nsamples = 54\nvalue = [0, 49, 5]\nclass = versicolor", fillcolor="#39e581e5"] ;
2 -> 3 ;
4 [label="gini = 0.043\nsamples = 46\nvalue = [0, 1, 45]\nclass = virginica", fillcolor="#8139e5f9"] ;
2 -> 4 ;
}

 





마지막으로, 위의 iris_tree.dot 의 dot format파일을 가지고 pygraphviz 패키지를 사용하여 Decision Tree를 시각화해보겠습니다. 





import pygraphviz as pgv

from IPython.display import Image

graph = pgv.AGraph("/Users/ihongdon/images/decision_trees/iris_tree.dot")

graph.draw('iris_tree_out.png', prog='dot')

Image('iris_tree_out.png')

 




[Reference]

  • Graphviz: https://graphviz.gitlab.io/
  • PyGraphviz: https://pygraphviz.github.io/


많은 도움이 되었기를 바랍니다. 


728x90
반응형
Posted by Rfriend
,

Jupyter Notebook 이나 ipython 을 사용하다보면 향후 버전이 올라갈 때 변경될 사항 등을 알려주는 경고 메시지(warning message)가 거슬릴 때가 있습니다. 


이럴 때는 warnings 라이브러리를 사용해서 


 - (1) 경고 메시지를 무시하고 숨기거나 (Ignore warning message)

    : warnings.filterwarnings(action='ignore')


 - (2) 숨기기했던 경고 메시지를 다시 보이게 (Reset to default)

    : warnings.filterwarnings(action='default')


하면 됩니다.  


별 내용은 없는 포스팅이긴 한데요, 이게 또 몰라서 경고 메시지가 주피터 노트북의 화면을 잔뜩, 계속 채우는 걸 보고 있노라면 은근히 신경이 쓰이기도 하거든요. ^^; 




아래에는 경고 메시지가 나타났을 때 

import warnings

warnings.filterwarnings(action='ignore') 

로 경고 메시지를 무시하고 숨기기를 했다가, 


warnings.filterwarnings(action='default')

를 사용해서 다시 경고 메시지가 나타나게 해본 예제입니다. 




많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. 



728x90
반응형
Posted by Rfriend
,