티스토리 툴바


modules2012/02/24 13:42

수행되고 있는 프로세서의 종류를 알고 싶은 경우나 해당 process를 kill하고 싶을 때 psutil module을 이용한다.

http://code.google.com/p/psutil/ 에서 psutil-0.4.0.win32-py2.7.exe를 다운 받아 설치하면 된다.

아래의 예는 현재 수행되고 있는 process의 id와 이름을 출력하는 예이다. 좀 더 자세한 내용은 homepage를 참고하면 된다.

import psutil
plist = psutil.get_pid_list()

for pid in plist :
    p = psutil.Process(pid)
    print pid, p.name


Posted by ce
modules2011/03/02 15:07

Module을 설치하는 경우 *.exe, easy_install 또는 source를 받아 compile하는 방법등이 있다.
Source를 받아 compile하는 경우 pre-requisite가 있는 경우 설치가 쉽게 되지 않은 경우가 있다.
예를 들어 pyopencl을 설치하려면 boost library가 있어야 하는데, boost library 자체도 설치가 만만치가 않다.

이러한 어려움을 없애기 위해 아래 link에 여러 library의 windows executable을 모아서 정리가 되어 있다.
http://www.lfd.uci.edu/~gohlke/pythonlibs/

참고로 위 site의 wavelet package인 "PyWavelets-0.2.0.win32-py2.6.‌exe" 는 link가 깨져 있지만 파일 name으로 search 하면 쉽게 구할 수 있다.
Posted by ce
modules2010/08/06 15:44
pymatlab을 ipython과 연동하여 사용하면 interactive하게 data 분석을 수행할 수 있다.
아래 code는 하나의 사용예이다.

put() 함수를 보면 ndarray가 아닌 value인 경우는 error가 발생해서 eval() 함수로 값을 설정하였다.
pymatlab 자체가 numpy와 연동하게끔 처음부터 설계된 것으로 보이는데, 실제로도 numpy와 같이 사용하는 것이 python과 matlab을 연동하는 의의를 찾을 수 있을 것 같다.

from pymatlab.matlab import MatlabSession
import numpy as np
import os

class matlabWork :
    def __init__(self) :
        ' open matlab session '
        self.session = MatlabSession()
        self.session.run("cd %s" % os.getcwd())
    def __del__(self) :
        ' close matlab session '
        self.session.close()

    def get(self,name) :
        return self.session.getvalue(name)
    def put(self,name,value) :
        if type(value) != np.ndarray : 
            self.session.run("eval('%s=%s')" % (name,value))
        else : 
            self.session.putvalue(name,value)
    def mrun(self,fname) :
        self.session.putstring('script__',open(fname).read())
        self.session.run("eval(script__)")

m = matlabWork()

Posted by ce
modules2010/08/03 20:10

What is pymatlab ?

Python numpy module을 이용하면 간단한 수학 계산등에는 편하지만 좀 만 더 진행하면 matlab의 막강한 function들이 필요해지곤 한다. 그렇다고 matlab만 사용하기에는 programming의 불편함과 다른 module과의 interface가 힘들어지곤 한다. Pymatlab module python matlab사이에서 데이터를 쉽게 주고 받을 수 있게 함으로써 서로의 장점을 취하고자 하는 module이다. Python matlab을 동시에 사용하는 경우 꼭 설치해서 사용해 보면 왜 이런 것을 진작 몰랐을까 하는 마음이 들 정도이다.

 

아래의 내용들은 window환경에서 python2.6 numpy 1.4, pymatlab 0.1.3 그리고 MATLAB R2010a을 사용하였다.

 

Install

pymatlab은 설치하기가 좀 까다롭다. 그렇다고 자세히 설명되어 있는 것도 없어 python module설치하는데 4-5시간이 소요되긴 했지만 결과는 기대이상이다. 아마 pymatlab version이 올라가면서 설치가 좀 더 편해지리라 생각한다.

 

1. 먼저 numpy setuptools를 설치한다. Setuptoolssetuptools-0.6c11.win32-py2.6.exe를 구해서 설치하면 되고 여기까지는 별 문제가 없다. 그리고 system pathC:\Python26\scripts를 꼭 포함시킨다.

 

2. include 복사

pymatlab 0.1.3 download해서 압축을 푼 후 pymatlab-0.1.3\src directory matlab.c을 살펴본다.

#include <numpy/arrayobject.h>

#include <engine.h>

위와 같이 include를 해야 하는데 arrayobject.h numpy에서 사용하는 것이고, engine.h matlab에 있는 파일이다. 해당 파일들을 찾아 python include에 복사한다.

 

C:\Python26\Lib\site-packages\numpy\core\include에 보면 numpy 디렉토리가 있는데 통째로 C:\Python26\include로 복사한다.

C:\Program Files\MATLAB\R2010a\extern\include에 보면 engine.h와 기타 파일들이 있는데 마찬가지고 통째로 C:\Python26\include로 복사한다.

 

3. library 복사

Matlab.c link하려면 matlab library가 필요한데 해당 compiler에 맞는 파일들을 복사해야 한다.

C:\Program Files\MATLAB\R2010a\extern\lib\win32\microsoft library 파일들이 여러 개 있는데 모두 C:\Python26\libs로 복사한다.

 

4. pymatlab을 압축 푼 곳에서 “python setup.py install”을 수행시킨다.

Error 발생시 위의 2,3과정을 다시 꼼꼼히 살핀다. 여기까지 성공하면 힘든 과정은 다 끝나고 마지막 path만 설정하면 된다.

 

5. 이제 마지막 단계로 system path matlab DLL 위치를 포함시켜야 한다.

C:\Program Files\MATLAB\R2010a\bin\win32 matlab이 사용하는 DLL이 있는데 이 path system path에 포함한다.

 

(새로 설치한 환경에서의 errror)

VC++2010 (express version도 마찬가지)이 깔려 있는 환경에서 위의 과정을 수행하면 아래와 같은 error가 발생한다.


building 'pymatlab.matlab' extension
error: Unable to find vcvarsall.bat


이는 python2.6, python2.7 visual studio 2008로 compile되어서 그렇다.

2010을 지우고 2008을 깔고 수행하면 된다.

참고로 새로 install한 환경은 python2.7과 MATLAB R2008b 이었는데, 문제 없이 설치된다.


Using pymatlab

from pymatlab.matlab import MatlabSession

import numpy as np

session = MatlabSession()

a = np.arange(10).reshape(2,5)

print a

session.putvalue('a',a)

session.run('b=2.*a')

b = session.getvalue('b')

print b

mscript = '''

d = a

for i=1:10

    d = 2*d

end

'''

session.putstring('MSCRIPT',mscript)

session.run('eval(MSCRIPT)')

d = session.getvalue('d')

print d

session.close()

 

위에서와 같이 수행하면 matlab session이 열어야 하기 때문에 시간이 많이 걸리므로 독립적으로 사용하기보다는 python ipython module에서 matlab session과 동시에 사용하는 것이 좀 더 편리하고 pymatlab의 장점을 더 많이 취할 수 있다.


Posted by ce
modules2010/08/03 19:10

 

python module로만 구성되는 경우

setup.py

from distutils.core import setup

setup(name='cetest',

      version='1.0',

      py_modules=['cetest'],

      )

 

cetest.py

def test(a) :

    return a + 10

print 'test lib imported'

 

Command console에서 setup을 수행시킨다.

python setup.py install

 

잘 수행되고 나면 lib/site-packages에 해당 파일이 위치하는 것을 확인할 수 있다.

이제 해당 모듈이 제대로 설치 수행되는지 확인해보자.

>>> import cetest

>>> print 'here %s' % cetest.test(1)

test lib imported

here 11

 

위의 code를 수행시키면 아래와 같은 결과가 출력되어 제대로 설치되었음을 확인할 수 있다.

 

 

Python module package로 구성하기

위의 예에서는 setup.py와 관련 파일들이 같은 디렉토리에 존재하였고, 여러 개의 module들을 만들게 되면 lib/site-packages에 설치되기 때문에 디렉토리가 복잡해진다. Package로 구성하면 이러한 부분을 깔끔하게 정리할 수 있다.

 

Source setup.py가 있는 디렉토리에 package directory를 만들고 그 안에 빈 내용의 __init__.py를 만들면 된다. 그리고 package directory에 해당 모듈을 작성하면 된다.

Director의 구성은 다음과 같다.



setup.py

src/

    __init__.py

    cetest.py

    cetest2.py


 해당 파일들의 내용은 다음과 같다.

 

__init__.py

from cetest import *

 

setup.py

from distutils.core import setup

setup(name='cetest',

      version='1.0',

      packages=['mypkg'],

      package_dir={'mypkg': 'src'},

      )

cetest.py

import cetest2

def test(a) :

    return cetest2.test2(a) + 10

print 'test lib imported'

 

cetest2.py

def test2(a) :

    return a * 10


설치가 되었는지는 다음과 같이 확인한다.

>>> import mypkg

>>> print 'here %s' % mypkg.test(1)

test lib imported

here 20

 

Package를 배포하려면 다음과 같이 수행한다.

python setup.py sdist   => mypkg-1.0.zip이 생성되고 이를 배포하면 된다.

 

Source가 아닌 binary로 배포하려면 아래와 같이 수행한다.

python setup.py bdist_wininst  => mypkg-1.0.win32.exe 이 생성됨을 알 수 있다.



Posted by ce
modules2009/10/26 07:59
data를 binary string으로 표현할 때 struct module을 사용한다.
numpy module의 tofile() 함수를 사용해도 쉽게 binary string으로 변경할 수 있지만 struct module을 사용하면 다른 형식의 data를 저장하기 쉽고, little endian뿐만 아니라 big endian으로도 표현하기 쉬운 장점이 있다.
예를 들어 network 통신을 할 때나 power pc와 같은 big endian을 사용하는 cpu와 데이터를 주고 받을 때 사용하게 된다.

python data를 binary로 변경할 때 pack() 함수를 사용하고, binary string을 python data로 변경할 때 unpack() 함수를 사용한다.

struct.pack(fmt, v1, v2, ...)
struct.unpack(fmt, string)

import struct

s = struct.pack('III', 1, 2, 3)         # I : unsigned integer format, i : integer format
open('test.bin','wb').write(s)

위의 코드로 파일을 생성하면 "01 00 00 00 02 00 00 00 03 00 00 00"와 같이 저장됨을 확인할 수 있다.
여기서 big endian으로 저장하려면, format string 앞에 '>' 을 붙이면 된다.

struct.pack('>III', 1, 2, 3)       => "00 00 00 01 00 00 00 02 00 00 00 03"

Binary string에서 python data를 얻으려면 unpack을 사용한다. 아래 예는 1,2,3를 big endian으로 바꾼 후 다시 interger를 읽어들인다.

import struct
s = struct.pack('>III', 1, 2, 3)
i1,i2,i3 = struct.unpack('>III',s)
print i1,i2,i3   # => 1 2 3

위의 예제에서는 integer만 사용하였는데, 여러 format 형식들은 python documentation에서 확인할 수 있다.


Posted by ce
modules2009/09/09 18:12

Python과 DLL 사이에서의 interface방법에 대해 알아보자. DLL interface는 확장 DLL이 아닌 Generic DLL만 다룬다. 

simple interface
C part
아래 코드를 이용하여 dll을 만든다.
#include <stdio.h>

extern "C" _declspec(dllexport) int testDLL(void);

int testDLL(void)
{
    printf("Hello world\n");
    return 1;
};

python에서는 ctype을 사용하여 DLL을 load한 후 call하면 된다.
from ctypes import *
dll = cdll.LoadLibrary('debug/ssdll.dll')
dll.testDLL()

hello world가 출력됨을 확인할 수 있다. 위의 내용이 visual C++ 파일로 첨부되어 있다.

Argument 전달
처음의 예는 argument 없이 함수 call만 하였는데 인자를 전달해 보자. 인자는 python에서 c_double(), c_int(), c_char_p(), c_long()을 사용하여 전달하면 된다.
int testDLL2(int a, float b)
{
    return int(a + b);
}  
int testDLL3(char *p)
{
    printf(p);
    return 1;
};

# python
print dll.testDLL2(c_int(3),c_float(5.7))
dll.testDLL3(c_char_p('Hello from python'))

참고로 integer나 char pointer인 경우 c_int(), c_char_p()를 생략해도 된다.


callback 함수
python에서 DLL에 있는 함수를 call 할 수 있고, 또한 C에서 python 쪽의 함수를 call하거나 변수의 값을 읽어들일 수 있다.
이것에 대해서는 첨부된 파일을 참조하면 별다는 어려움없이 이해할 수 있으리라 생각된다.

첨부된 파일은 Visual C++ 2008 express version으로 작성되었다.


Posted by ce
modules2009/08/13 16:14
python에서 matlab의 mat file을 읽거나 쓰려고 하면 scipy.io module의 loadmat, savemat 함수를 사용하면 쉽다.

matlab에서 data와 description을 저장한다. matlab에서 아래 코드를 수행시키면 test3.mat이 생성된다.

>> data = 1:10;
>> data = reshape(data, 2, 5)

ans =

     1     3     5     7     9
     2     4     6     8    10

>> description = 'test data from matlab';
>> save test3.mat data description;


 python에서 읽으면 data와 description이 dictionary의 key로 들어오게 된다. 

import scipy.io
mat = scipy.io.loadmat('test3.mat')
data = mat['data']
description = mat['description']

print data.shape
print data
print description

출력 결과
(2, 5)
[[ 1  3  5  7  9]
 [ 2  4  6  8 10]]
[u'test data from matlab']
위의 코드를 수행시키면 matlab에서 만든 data가 제대로 읽어짐을 확인할 수 있다.

그러면 이제 savemat 함수를 이용하여 python에서 mat file을 만들어보자.

mdata = {}
data = numpy.arange(1,11)
mdata['data'] = data.reshape(2,5)
mdata['description'] = 'test data from python'
scipy.io.savemat('test4.mat',mdata, do_compression=True)
matlab version 7에서는 compression을 default로 하니까 (당연히 바꿀 수는 있다.) python에서도 do_compression flag를 사용해서 compression을 하였다.

matlab에서 load test4.mat으로 읽으면 된다.
>> load test4.mat
>> data

>> data

data =

           1           2           3           4           5
           6           7           8           9          10

>> description

description =

test data from python



Posted by ce
modules2009/06/06 17:05

가끔은 정확한 위치에 이미지를 만들 경우가 생기는데 numpy와 Image module을 사용하면 GIF 파일을 쉽게 만들 수 있다.

아래의 예는 256 by 256 크기에 중앙에 128 by 128의 사각형을 그린다.

 

from numpy import *
import Image as PIL

iwidth = 256
iheight = 256
a = zeros((iwidth,iheight))

N = 128
for i in range(-N/2, N/2) :
    for j in range(-N/2, N/2) :
        a[iheight/2 + i][iwidth/2 + j] = 255

a = a.astype('b').tostring()

# make gif file
im = PIL.new('P', (iwidth,iheight))  # palette mode
im.fromstring(a)
im.show()
im.save('test1.gif')

 

 

Posted by ce
DSP2009/06/06 17:02
numpy를 이용하여 binary file을 다루는 예제이다. 사용하는 method는 tofile, fromfile이다.

fromfile에서 사용하는 flag의 종류는
  • 'h' : 16bits signed integer
  • 'H' : 16bits unsigned integer
  • 'f', 'f4' : 4bytes float
  • 'i1', int8 : 1 byte signed integer
  • 'i', 'i4', int32 : 4bytes signed integer
  • uint8 : 1 byte unsigned integer
  • uint32 : 4bytes unsigned integer

from numpy import *

a = arange(16)
a = a.astype('h')
a.tofile('test.bin')
a = a.reshape((1,16))
print a

c = fromfile('test.bin','h')
c = c.reshape((2,8)).transpose().reshape((1,16))
print c

출력결과는 아래와 같다.
[[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15]]
[[ 0  8  1  9  2 10  3 11  4 12  5 13  6 14  7 15]]

참고로 test.bin의 내용은 다음과 같다.
0000000: 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00
0000010: 08 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 0f 00

Posted by ce