IPython 에서 matplotlib import 시 cannot import name 'QtCore' 오류 발생 처리


Think Stats 2 PDF 를 보다가 첫 SOURCE 코드를 테스트 시 오류가 발생하였다.

확인해 보니 IPython에서 matplotlib 를 import 시 cannot import name 'QtCore' 오류 발생 처리


내 PC의 Python 버전은 3.4이다. , matplotlib 를 import 시 QtCore 5와 QtCore 4 간에 불일치로 문제가 발생되는 것 같다.

아래와 같이 matplotlib.use("Qt5Agg") 를 IPython에서 수행하여 해결하였다. 이 때 주의할 사항이 있는데 오류가 난 Ipython 콘솔에서 해당 설정을 수행하면 Warning 메시지가 나오면서 이미 Backend가 설정되어 해당 설정은 적용되지 않는다는 것이다. 반드시 새로운 콘솔창을 열고 해당 명령어를 입력하자.


import matplotlib


matplotlib.use("Qt5Agg")


C:\Anaconda3\lib\site-packages\matplotlib\__init__.py:1350: UserWarning:  This call to matplotlib.use() has no effect
because the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

반드시 새로운 콘솔창을 열고 해당 메시지를 입력하자.



Numpy 와 Pandas에서 불리언 색인의 활용

Numpy  불리언 색인 기능 소개.


정규 python의 리스트 중첩과 유사하나 보다 쉽게 if 문의 활용 및 다양한 데이터 가공을 가능하게 함.


정규 python의 리스트 중첩은 아래와 같다.


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

#이를 리스트 중첩으로 3보다 큰 리스트를 추출할 수 있다.

[x for x in array1 if x > 3]

Out[39]: [4, 5] 


Numpy 에서는 보다 쉽게 array 를 추출 가능.


import numpy as np

array2 = np.array([1,2,3,4,5])

# numpy array 에서 비교 연산자를 바로 적용 시 각 array 값 별로 True , False 값을 반환.

array2 > 3

Out[44]: array([False, False, False,  True,  True], dtype=bool)

# 1차원 배열에서 3보다 큰 값을 모두 추출함.

array2[array2 > 3]

# True에 해당하는 index array 값만 반환. 

Out[45]: array([4, 5])


불리언 색인은 array의 색인이 True, False 값을 가지게 하여 True 인 경우에 해당 array 값을 출력하게 함.



다음 예제는 Python for Data Analysis 에서 가져온 것이다.

2차원 Numpy 배열에 불리언 색인을 적용한 예제다.


names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])

names

Out[48]:

array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],

      dtype='<U4')

data = np.random.randn(7,4)

data

Out[50]:

array([[-1.26013079,  0.29081568,  1.87164573,  0.66950956],

       [-1.18357656,  1.61485173, -0.93498466,  0.62553805],

       [-0.35840121, -0.2164986 , -0.59688896, -0.49594989],

       [ 0.88574796, -0.28987652, -1.1023612 ,  0.55036842],

       [ 0.04366381, -0.57763389,  0.16284361, -0.46842905],

       [-0.13914101, -1.09840424,  0.16332229,  0.21295691],

       [ 0.61643143, -1.94844699,  0.18180573, -0.8689196 ]])




비교 연산자 == anames array 에 바로 적용할 때 True,False 값이 각 array 값에 설정되며 이를 불리언 색인으로 사용할 수 있다.  array[0] array[3] 만이 True 이다

names == 'Bob'

Out[51]: array([ True, False, False,  True, False, False, False], dtype=bool)



2차원 배열인 data에 바로 불리언 색인을 적용할 수 있다. Array[0]array[3] True 이므로 data 배열에서 1행과 4행만을 출력한다.

data[names=='Bob']

Out[52]:

array([[-1.26013079,  0.29081568,  1.87164573,  0.66950956],

       [ 0.88574796, -0.28987652, -1.1023612 ,  0.55036842]])


출력하려는 행렬을 슬라이스나 숫자 색인을 줘서 제한 할 수 있다. 위의 경우는 불리언 색인으로 추출된 배열에서 2: 3열 이후의 값을 추출함.

data[names=='Bob',2:]

Out[55]:

array([[ 1.87164573,  0.66950956],

       [-1.1023612 ,  0.55036842]])


논리연산자를 이용하여 보다 복잡한 조합도 가능하다.

& (And) , | (Or) 논리 연산자를 이용한 불리언 색인 결과

(names == 'Bob') | (names =='Will')

Out[65]: array([ True, False,  True,  True,  True, False, False], dtype=bool)

data[ (names=='Bob') | (names == 'Will') ]

Out[61]:

array([[-1.26013079,  0.29081568,  1.87164573,  0.66950956],

       [-0.35840121, -0.2164986 , -0.59688896, -0.49594989],

       [ 0.88574796, -0.28987652, -1.1023612 ,  0.55036842],

       [ 0.04366381, -0.57763389,  0.16284361, -0.46842905]])


불리언 색인에 기반한 값 대입도 가능하다.

data < 0

Out[66]:

array([[ True, False, False, False],

       [ True, False,  True, False],

       [ True,  True,  True,  True],

       [False,  True,  True, False],

       [False,  True, False,  True],

       [ True,  True, False, False],

       [False,  True, False,  True]], dtype=bool)



# 값 대입

data[data < 0 ] = 0

data

Out[68]:

array([[ 0.        ,  0.29081568,  1.87164573,  0.66950956],

       [ 0.        ,  1.61485173,  0.        ,  0.62553805],

       [ 0.        ,  0.        ,  0.        ,  0.        ],

       [ 0.88574796,  0.        ,  0.        ,  0.55036842],

       [ 0.04366381,  0.        ,  0.16284361,  0.        ],

       [ 0.        ,  0.        ,  0.16332229,  0.21295691],

       [ 0.61643143,  0.        ,  0.18180573,  0.        ]])




다음은 Pandas 에서 이러한 불리언 색인에 기반한 호출을 수행해보자


비교연산자 >= pandas DataFrameValueTrue, False 값이 인덱스별로 설정됨.


df = pd.DataFrame(

{

'AAA':[4,5,6,7],'BBB':[10,20,30,40],'CCC':[100,50,-30,-50]

}

)

df

Out[82]:

   AAA  BBB  CCC

0    4   10  100

1    5   20   50

2    6   30  -30

3    7   40  -50



df.AAA >=5

Out[74]:

0    False

1     True

2     True

3     True

Name: AAA, dtype: bool



AAA 필드가 5보다 크거나 같은 인덱스의 값만이 출력됨.  

df[df.AAA >=5]

Out[73]:

   AAA  BBB  CCC

1    5   20   50

2    6   30  -30

3    7   40  -50




ix 함수를 사용하면 더욱 다양한 활용이 가능하다.

Ix 를 이용하여 원하는 필드만 추출 가능하다. 위 예제 에서는 AAA BBB 컬럼만을 추출하였다.

물론 동일한 결과를 아래의 Slicing 을 통해서도 얻을 수 있다.

df.ix[df.AAA >=5]

Out[72]:

   AAA  BBB  CCC

1    5   20   50

2    6   30  -30

3    7   40  -50

df.ix[df.AAA >=5 ,['AAA','BBB']]

Out[78]:

   AAA  BBB

1    5   20

2    6   30

3    7   40

df.ix[df.AAA >=5, :2]

Out[79]:

   AAA  BBB

1    5   20

2    6   30

3    7   40




데이터의 입력도 가능하다.
AAA 컬럼값이 5 이상인 레코드를 대상으로 BBB 컬럼을 -1 로 새롭게 입력하였다.


df.ix[df.AAA >=5,'BBB'] = -1

df

Out[84]:

   AAA  BBB  CCC

0    4   10  100

1    5   -1   50

2    6   -1  -30

3    7   -1  -50





Pandaswhere 함수를 사용하면 기존 값의 가공에 따라 데이터를 새로운 컬럼값으로 입력할 수 있다.

In [7]: df = pd.DataFrame( ...: {'AAA' : [4,5,6,7], 'BBB' : [10,20,30,40],'CCC' : [100,50,-30,-50]})

df ...: Out[7]:

AAA BBB CCC

0 4 10 100

1 5 20 50

2 6 30 -30

3 7 40 -50

In [8]: df['logic'] = np.where(df['AAA'] > 5,'high','low')

df

Out[8]:

AAA BBB CCC logic

0 4 10 100 low

1 5 20 50 low

2 6 30 -30 high

3 7 40 -50 high



With as 절이 도입되기 이전에는 File i/o 처리를 위해 다음과 같이 fileopen 하고 close 하는 routine 을 수행해줘야 한다.

f= open(“ 파일명”, “r+”)

Line = f.readline()

f.close()


특히 file I/O시 오류발생에 대응하기 위해서 file open close 시에 try : except : finally: 절을 이용하여 I/O 에러 처리 및 close 처리를 해줘야 한다.

f=None

Try :

  f= open(“파일명”,”r+”)

                           line = f.readline()

Except:

  pass

Finally:

  f.close()


그러나 with .. As 절을 이용하면 try , except,finally 를 이용하지 않고도 자동으로 file close 해줄 수 있다.

With open(“파일명”,”r+”) as f

  f.readline()

개요


항목

설명

내용 및 특징

Memory mapped File File I/O Virtual Memory 처리 기반에서 수행할 수 있게 해준다.


Memory API를 이용하여 File I/O Api를 대신할 수 있으므로 보다 쉬운 API 사용이 가능.

장점

File Buffer 를 거치지 않고 Memory에서 I/O Direct access 하고, 4K 단위의 Memory page

이용하므로 I/O 성능을 개선


여러 프로세스끼리 공유파일이 가능.

단점

32bit 시스템에서 4G 이상의 파일은 수용할 수 없음.

처리해야 할 에러 유형이 상대적으로 많음.


주요 특징

Memory mapped filefile object , string object 둘 다를 지원하는 다양한 api 를 가지고 있다. Close(),flush(),read(),readline(),seek(),tell(), write() 와 같은 file api slicing 이나 find와 같은 string api 도 지원함.

Mmap.mmap() 함수로 반환된 object 에 대해서 리스트연산, slicing 등 기존 문자열 처리에 사용되는 api 를 이용하여 다양하게 가공이 가능하다.


API 설명


UnixWindow 간 함수 인자값에 차이가 있으므로 주의가 필요하다. 
class mmap.mmap(fileno, length[, flags[, prot[, access[, offset]]]])  로 호출된다.
Filenoopen(파일명) 으로 반환된 File descriptor ,
length 는 메모리로 매핑할 파일의 크기, 0 으로 설정 시 파일 전체를 메모리로 매핑
Flags 는 메모리매핑의 공유 특성을 나타냄. MAP_SHARED 가 디폴트이며 이 경우 다른 프로세스가 해당 파일 매핑을 변경할 시 다른 프로세스도 이를 공유할 수 있다. MAP_PRIVATE 는 프로세스별로 별도의 COPY_ON_WRITE 공간을 가지므로 개별 프로세스의 파일 매핑 변경사항이 공유되지 않는다.
Access  ACCESS_READ, ACCESS_WRITE, or ACCESS_COPY 로 읽기, 쓰기 , 복사용도를 나타냄.  ACCESS_COPY 의 경우는 변경사항을 메모리에만 적용하고 파일에는 적용하지 않는다.
Prot 는 메모리 protection 을 나타내며, PROT_READ and PROT_WRITE 가 사용됨.  디폴트는 PROT_READ | PROT_WRITE 이며 해당 메모로기 read 또는 write 로 사용 될 수 있음을 의미함.



연산을 수행하다보면, 동적으로 할당된 array 에 대해서 몇행, 몇열 행렬로 구성되었는지 알아야 할 경우가 있다. 
이 경우 array의 shape 를 이용하여 간단하게 알 수 있다.  


a = np.array( [ [
1,2,3],[4,5,6],[7,8,9],[10,11,12] ])
# a 는 3 x 3 행렬로 구성됨.

print(a.shape)


print 결과는 (4,3 ) 임.


추가로 shape[0], shape[1]를 이용하여 전체 행의 갯수와 열의 갯수를 반환받을 수 있다.

즉 a.shape[0] 결과는 4임(shape 튜플의 첫번째 요소는 4) , a.shape[1]의 결과는 3임(shape 튜플의 두번째 요소는 3).


Python에서는 ++ 나 -- 와 같은 증감 연산자가 없다. 
만일 아래와 같이 int 형 변수에 ++ 를 사용하게 되면 증감연산자로 작용하지 않고 아무 의미 없이 사용된다. 

a = 1
++a
print (a)
결과는 1 임

"파이썬을 이용한 시스템 트레이딩" (https://wikidocs.net/book/110) 문서를 따라하던 중에 약간의 오류가 발생하였다.

확인해 보니 , 해당 자료는 PyQt4 기준인데, 내 PC의 Anaconda는 PyQt5 가 인스톨되어 있었다. 
PyQt5에는 이벤트 처리 시 connect 함수가 다르게 호출되어야 한다. 

PyQt4 에서는 QMainWindow 를 상속받아서 self.connect 함수의 인자에 이벤트를 발생 시킨 객체명, 발생 이벤트명, 이벤트 처리기에서 수행 함수명을 기재한다.  self.connect(self.pushButton, SIGNAL("clicked()"),self.btn_clicked) 와 같이 호출한다. 
PyQt5 에서는 객체의 이벤트에서 connect 함수를 호출하고 인자에 이벤트 처리기에서 수행하는 함수를 기재한다. 
self.pushButton.clicked.connect(self.btn_clicked) 와 같이 호출한다. 

아래는 PyQt4 의 예제임. 
import sys

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import uic


form_class = uic.loadUiType("main_window.ui")[0]

class MyWindow(QMainWindow , form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        #pushButton은 이벤트를 발생시킨 QPushButton 객체명,
        #SIGNAL("clicked")는 QPushbutton의 클릭 함수,
        #self.btn_clicked 는 QPushbutton 클릭시 Event 처리기에서 수행하는 함수
        self.connect(self.pushButton, SIGNAL("clicked()"),self.btn_clicked)

    def btn_clicked(self):
        QMessageBox.about(self,"message","clicked")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()


아래는 PyQt5 의 예제임. 
import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
import signal
from PyQt5.QtWidgets import *
from PyQt5 import uic


form_class = uic.loadUiType("main_window.ui")[0]

class MyWindow(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        #객체의 이벤트에서 connect 함수를 호출하고 인자에 이벤트 처리기에서 수  행하는 함수를 기재한다. 
        self.pushButton.clicked.connect(self.btn_clicked)

    def btn_clicked(self):
        QMessageBox.about(self"message""clicked")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()

요즘 파이썬을 공부하고 있는데, 파이썬 2.7 로 실습하다가 , 파이썬 3으로 바꾸다보니 기존에 사용하던 print 함수가 제대로 동작하지 않는 경우가 있음.


제일 중요한것은 2.7 버전에서는 print 가 괄호없이도 사용가능하였으나 3버전에서는 반드시 괄호를 사용해야 한다.


먼저 2.7 버전에서는


1. print 가 괄호 없이 사용 가능함. 즉 print "test123"  이 가능

2. C 언어의 printf와 같이 %d, %f 등의 포맷팅 사용 가능

print " test%3d " % (123)

3. format 내장함수를 이용하여 format

print "test{0} ".format(123)


그런데 3 버전에서는


반드시 괄호를 사용해야 하고, C언어의 printf 와 같은 형태의 포맷팅은 사용 불가하다. 그리고 포맷팅은 format 내장함수와 {} 기호를 이용한다.

print "test{0} ".format(123)


기존의 2버전 print "test%3d " % (123)의 경우에는

print ("test{:3d}".format(123)) 으로 변환

C의 printf 포맷팅에 사용되는 %3d 의 경우 {:3d} 로 변경되고 .format 을 이용하여 해당 포맷대로 값을 입력된다.



기존 2버전의 경우에 C형식의 printf 포맷팅이 지원되어 매우 반가웠는데, 3버전에서는 이에 대한 지원이 중단되어서 아쉬움이 남는다.


2버전에서 3버전의 주요 변화는 아래에 좋은 자료가 있으니 참조하기 바란다.

https://wikidocs.net/743

+ Recent posts