세상에... Python으로 이렇게 간단힌 n-gram을 만들 수 있다니...!!


우선 zip 함수에 대해 알아보자. zip함수의 인자로 받은 리스트 등의 iterator들을 묶어주는 함수이다. 뭐 예를 들면...


>>> q = [1,2,3,4,5]

>>> w = [10, 20, 30, 40,50]

>>> r = [100, 200, 300, 400, 500]

>>> zip(q, w, r)

[(1, 10, 100), (2, 20, 200), (3, 30, 300), (4, 40, 400), (5, 50, 500), (6, 60, 600)]


이제 n-gram을 만들어보자. 위의 방법으로 만들기 떄문에 함수도 짧고 속도도 그만큼 빠르다.


>>> a = "I am a boy, you are a girl."

>>> b = a.split(" ")
['I', 'am', 'a', 'boy,', 'you', 'are', 'a', 'girl.']
>>> zip(b, b[1:])
[('I', 'am'), ('am', 'a'), ('a', 'boy,'), ('boy,', 'you'), ('you', 'are'), ('are', 'a'), ('a', 'girl.')]


b 리스트와 b 리스트 중 0번째 원소를 제외하고 1번째 원소부터 시작한 리스트를 zip으로 묶은 결과이다. 이렇게 bi-gram을 만들 수 있다. 


그럼 n-gram은...? 다음과 같이 만들면 된다고 한다. 


>>> zip( *[b[i:] for i in range(3)] )

>>> [('I', 'am', 'a'), ('am', 'a', 'boy,'), ('a', 'boy,', 'you'), ('boy,', 'you', 'are'), ('you', 'are', 'a'), ('are', 'a', 'girl.')]


원리는 간단하다. 

1. 리스트 내포(list comprehension) 문법으로 b[0:], b[1:], b[2:], ... 등의 리스트를 원소로 가지는 리스트를 하나 만든다. 

2. 만들어진 리스트의 원소들이 필요하기 때문에, 리스트 앞에 *을 붙여 리스트의 원소들이 함수의 argument로 들어가도록 해준다.

3. zip으로 묶어준다. 


새로 발견한건 아니고... 출처는 아래이다. Python 짱이네..

http://locallyoptimal.com/blog/2013/01/20/elegant-n-gram-generation-in-python/


'Study > Computer' 카테고리의 다른 글

large data with numpy  (0) 2014.06.20
numpy array 잘라쓰기  (0) 2014.06.17
Matplotlib 추천 Q&A 링크들  (0) 2014.05.21
위도, 경도 검색 프로그램  (0) 2014.05.09
Too many open files 에러가 로그에 남을 때  (0) 2014.04.07

매번 업데이트하고 있습니다. 


* Multiple Plot 그릴 때 (특히 legend를 같이 그리고 싶을 때)

http://stackoverflow.com/questions/5484922/secondary-axis-with-twinx-how-to-add-to-legend


* Bar chart에서 bar 마다 색을 다르게 주기

http://stackoverflow.com/questions/18973404/settting-different-bar-color-in-matplotlib-python


* Scatter Plot 에서 point 에 색을 주기 (colormap 도 같이 있음)

http://stackoverflow.com/questions/8202605/matplotlib-scatterplot-colour-as-a-function-of-a-third-variable

http://matplotlib.org/examples/pylab_examples/scatter_demo2.html


* Plot에서 error를 색으로 칠하기

http://stackoverflow.com/questions/12957582/matplotlib-plot-yerr-xerr-as-shaded-region-rather-than-error-bars


* Legend 사이즈 조절하기

http://stackoverflow.com/questions/20048352/how-to-adjust-the-size-of-matplotlib-legend-box


* 그래프 퀴퉁이에 text 넣기

http://stackoverflow.com/questions/8482588/putting-text-in-top-left-corner-of-matplotlib-plot


* Colorbar 뒤집어 그리기 (cm에 있는 colorbar)

http://stackoverflow.com/questions/3279560/invert-colormap-in-matplotlib 

(가장 많은 추천의 답이 정답...!)


* 그림 png로 저장할 때 크기 및 해상도 조절하기

http://stackoverflow.com/questions/332289/how-do-you-change-the-size-of-figures-drawn-with-matplotlib


* PolyCollection 사용하기 (Polygon을 그리고 색을 정해줄 수 있음)

http://matplotlib.org/examples/api/collections_demo.html


* Discrete color bar 만들기 (polygon 색칠할 때 색을 정해줄 경우, 이걸로 우회하여 해결... 어떻게 폴리곤마다 색을 지정해주는지는 아직 모르겠음..)

http://stackoverflow.com/questions/14777066/matplotlib-discrete-colorbar


* Discrete color bar 만들기2 -> 자신이 원하는 색으로 만드는 방법. 꽤 쉬움..

http://stackoverflow.com/questions/9707676/defining-a-discrete-colormap-for-imshow-in-matplotlib


* Axis 눈금을 동등하게 그리기

http://matplotlib.org/examples/pylab_examples/axis_equal_demo.html


* Imshow에서 square 로 plot 하기. 사실 aspect 를 조절하면 되는데, 이걸 계산해서 square로 만들어줘야 하니까... 좀 번거로움. 

http://stackoverflow.com/questions/7965743/python-matplotlib-setting-aspect-ratio



* 3D plot from data

http://stackoverflow.com/questions/4363857/matplotlib-color-in-3d-plotting-from-an-x-y-z-data-set-without-using-contour

http://stackoverflow.com/questions/12730436/matplotlib-plotting-non-uniform-data-in-3d-surface


*Scatter plot에서 point마다 label 주기

http://stackoverflow.com/questions/5147112/matplotlib-how-to-put-individual-tags-for-a-scatter-plot (Gorgeous!)

http://stackoverflow.com/questions/14432557/matplotlib-scatter-plot-with-different-text-at-each-data-point (Basic)

'Study > Computer' 카테고리의 다른 글

numpy array 잘라쓰기  (0) 2014.06.17
Python으로 n-gram 만들기  (0) 2014.05.22
위도, 경도 검색 프로그램  (0) 2014.05.09
Too many open files 에러가 로그에 남을 때  (0) 2014.04.07
py2exe로 pyQT4 코드 exe로 만들기  (0) 2014.03.13

윈도우에서 easy_install로 beautifulsoup을 설치했더니 3.x 버전이 설치되었다...ㄷㄷ

BeautifulSoup4(이하 BS4)를 설치하는 방법도 쉬운데, easy_install로 하지말고 확실하게 다운로드 받아서 설치해보자.


1. 우선 아래 링크로 가서 최신 버전의 BS4 압축파일을 다운로드 받는다.

http://www.crummy.com/software/BeautifulSoup/bs4/download/


2. 압축을 풀면 안에 setup.py가 있는데 윈도우나 리눅스 모두 다음과 같이 설치하면 된다.

python setup.py build

후에

python setup.py install


3. 확인

python을 연 뒤에 다음처럼 BS4를 불러온다.

>>>> from bs4 import BeautifulSoup

문제없으면 성공.


6.1.8.py


Strogatz의 Nonlinear Dynamics 교과서에서 6장 연습문제에 보면 van der Pol oscillator가 나온다. 식은 다음과 같이 생겼다. 




이 미분방정식들의 Vector Field를 파이썬으로 그릴 수 있는데 최대한 matplotlib함수를 쓰지 않고(mgrid 등) 그리는 코드를 짰다. 거기에 덧붙여 임의의 점 하나를 잡고 trajectory를 시간에 대해 그리도록 하는 기능을 같이 넣었다. portrait 아래에 나오는 두개의 그래프는 x-t 그리고 y-t 그래프이다. 

trajectory를 따라가보면 시간이 조금 지난뒤에는 진동하는 모습을 보여주며 phase portrait에서도 볼 수 있다. 


Vector plot을 하게되면 trajectory가 뚜렷히 보이지 않는 단점이 있다. vector의 크기가 작을 경우 화살표가 상대적으로 작게 나와 잘 보이지 않기 때문인데, mathematica에서는 StreamPlot이라는 명령어로 trajectory들의 portrait를 살펴보기 쉽다. 하지만 matplotlib에서는 Stream을 plot해주는 함수가 없기 때문에 누군가 만들어 놓은 것이 있다. 아래 링크를 살펴보시면 된다.

http://stackoverflow.com/questions/8296617/how-to-plot-a-streamlines-when-i-know-u-and-v-components-of-velocitynumpy-2d


아래 코드에서간단히 1개의 trajectory를 그렸는데 이를 격자형태로 모두 계산해 그리면 Stream plot이 되는건 뻔한 이야기. -.- (하지만 이건 하고싶지 않아져서 패스)


프로그램을 실행시키면 아래와 같다. (이런걸 왜 넣고 있지.)

참! 예쁘게 나올 필요는 없어서 여백조정은 패스~(사실 이걸 알아보려고 또 20분남짓 소비하는게 싫어서...)




코드는 아래에~!


import numpy as np

import matplotlib.pyplot as plt


def xftn(x, y):

return y


def yftn(x, y):

tmp = -x + y*(1-x*x)

return tmp


def xRK4(x, y, dt):

    k1 = dt * xftn(x, y)

    k2 = dt * xftn(x + 0.5*k1, y + 0.5*k1)

    k3 = dt * xftn(x + 0.5*k2, y + 0.5*k2)

    k4 = dt * xftn(x + k3, y + k3)


    result = x + k1 / 6 + k2 / 3 + k3 / 3 + k4 / 6


    return result


def yRK4(x, y, dt):

    k1 = dt * yftn(x, y)

    k2 = dt * yftn(x + 0.5*k1, y + 0.5*k1)

    k3 = dt * yftn(x + 0.5*k2, y + 0.5*k2)

    k4 = dt * yftn(x + k3, y + k3)


    result = y + k1 / 6 + k2 / 3 + k3 / 3 + k4 / 6


    return result



Step = 0.1

xLeft = -2

xRight = 2

yTop = 2

yBottom = -2


SIZE = (int)((xRight-xLeft)/Step) + 1  #We only think square plane.


print("Step is", Step)


x = np.empty((SIZE,SIZE), float)

y = np.empty((SIZE,SIZE), float)


u = np.empty((SIZE,SIZE), float)

v = np.empty((SIZE,SIZE), float)


for i in range(SIZE):

for j in range(SIZE):

x[i][j] = xLeft + Step*i

y[i][j] = yBottom + Step*j

u[i][j] = xftn(x[i][j], y[i][j])

v[i][j] = yftn(x[i][j], y[i][j])


xPointList = [0.5]

yPointList = [0.5]

timeList   = [0]


dt = 0.01


for i in range(1500):

xPointList.append(xRK4(xPointList[i], yPointList[i], dt))

yPointList.append(yRK4(xPointList[i], yPointList[i], dt))

timeList.append(timeList[i]+dt)


ax1 = plt.subplot2grid((7,3), (0,0), rowspan=5, colspan=5)

ax1.quiver(x,y,u,v, angles='xy', pivot='middle')

ax1.plot(xPointList, yPointList)

plt.xlim(-2, 2)

plt.ylim(-2, 2)


ax2 = plt.subplot2grid((7,3), (5,0), colspan=3)

ax2.plot(timeList, xPointList)


ax3 = plt.subplot2grid((7,3), (6,0), colspan=3)

ax3.plot(timeList, yPointList)


plt.show()

파이썬으로 벡터장을 그려야 하는 경우가 있다. 심심하면 지도를 놓고 위에 풍향과 풍속을 그려볼 수도 있다. (기상청에서 데이터 받아서 그려보셔도 됩니다...정 심심하시면요...)


메뉴얼과 구글링을 통해서 더 깊이있는 방법들을 배울 수 있지만 가장 간단한 코딩은 아래와 같다.


import matplotlib.pyplot as plt

import numpy as np


x = np.empty((10,10), float)

y = np.empty((10,10), float)


u = np.empty((10,10), float)

v = np.empty((10,10), float)


for i in range(10):

    for j in range(10):

        x[i][j] =  i / 10.0

        y[i][j] =  j / 10.0

        u[i][j] =  i / 10 * 2 

        v[i][j] =  j / 10 * 2


print(x, y, u, v)


plt.quiver(x,y,u,v, angles='xy', pivot='middle')

plt.ylim(0,1.1)

plt.xlim(0,1.1)

plt.grid('on')

plt.show()


코드의 대부분은 그냥 정의하는거고....
벡터장을 그려주는 함수는 plt(matplotlib.pyplot)의 quiver라는 함수이다. 여기서 x, y는 벡터의 위치를 나타내며 u,v는 벡터의 성분을 말한다. angle은 벡터의 각도를 어디서부터 측정할꺼냐 그런 내용인데(아닐 수도 있음) 'xy'로 해야 우리가 상상하는 결과가 나온다. pivot은 벡터를 회전시킬 때 꼬리를 잡을지 머리를 잡을지 그것도 아니면 중간을 잡을지에 대한 옵션이다. 더 다양한 옵션은 공식 홈페이지를 참고하시고....

사실 mash를 이용해 u, v를 만들어도 된다. 여기서는 생략...

결과는 다음과 같다.




removetab.py


한 디렉토리 안에 있는 모든 데이터파일을 읽어서 중복된 tab을 없애고 다른 확장자로 저장하는 코드. python을 완전 잘하는 편이 아니어서 그냥 기초적인 방법으로 주욱주욱 만들었음...


import glob


Flist = glob.glob('*.txt')


OldExt = 'txt'

NewExt = 'dat'


for i in range(len(Flist)):

#Flist is str class !!!

fr = open(Flist[i], 'r')

fwriteName = Flist[i].replace(OldExt, NewExt)

fw = open(fwriteName, 'a')

print(Flist[i], "to", fwriteName)

ContentL = fr.readlines()

for j in range(len(ContentL)):

rowL = ContentL[j]

rowL = rowL.split('\t')

TabCnt = rowL.count('')

for k in range(TabCnt):

rowL.remove('')

#Change list to str with \t delimiter

rowStr = "\t".join(rowL)

fw.write(rowStr)


Class가 list인지 str인지에 따라 쓰이는 함수(method)가 다르기 때문에 꽤나 헷갈린다. 자주 다루지 않다보니 벌어지는일! 아무튼 이렇게 하면 중복된 tab을 없앨 수 있다. 


주의!!

용량이 큰 데이터파일들의 tab을 지워야 할 경우 이 프로그램은 컴터를 넉다운시킬수 있다. 왜냐면 readlines()로 그냥 한번에 주욱 읽어서 리스트로 저장하기 떄문이다... 메모리관리는 전혀 신경쓰지 않았는데 지금 다루는 데이터파일들 용량이 작은편이어서이다.ㅋㅋㅋ



+ Recent posts