Drkcore

11 03 2011 Python Tweet

Pythonのinspectモジュールを読んでみた。

今日も体調がすぐれないのというか、余計ひどくなった気がする(喉痛い)ので会社を休む。有休あまりまくってるしまぁここらへんで消費するのもいいかなと。

寝ながら本を読むにも軽めのちょうどいいのがないので、ソースコードリーディングでもとinspectを読んでみた。

getargs,getsource,classify_class_attrsあたりは参考になった。

こんな感じでK-meansのコードがあったとする。

from itertools import groupby
from math import sqrt

zipWith = lambda f, xs, ys : [f(x, y) for x,y in zip(xs, ys)]
snd  = lambda x: x[1]
fst  = lambda x: x[0]
euclid  = lambda x, y : (x-y)**2

def distance(a,b): 
    return sqrt(sum(zipWith(euclid,a,b)))

def centroid(clusters): 
    sums = reduce(lambda x,y: zipWith(lambda a,b:a+b,x,y),clusters)
    return map(lambda x: x / float(len(clusters)), sums)

def closest(pts, pt):
    closest_ct = pts[0]
    for ct in pts[1:]:
        if distance(pt,closest_ct) > distance(pt,ct):
            closest_ct = ct
    return closest_ct

def recluster_(centroids,points):
    reclustered = [(closest(centroids,a), a) for a in points]
    reclustered.sort()
    return [map(snd,list(g)) for k, g in groupby(reclustered, fst)]

def recluster(clusters):
    centroids = map(centroid, clusters)
    concated_clusters = reduce(lambda a,b: a+b, clusters)
    return recluster_(centroids,concated_clusters)

def part(l,points):
    size = len(l)/points
    return [l[i:i+size] for i in range(0,len(l),size)]

def kmeans(k,points):
    cluster = part(k,points)
    newcluster = recluster(cluster)
    while(cluster !=  newcluster):
        cluster = newcluster
        newcluster = recluster(cluster)
    return newcluster

if __name__ == "__main__":
    pts = [[1,2,4],[1,3,3],[4,3,0],[2,5,1],[7,3,8],[0,0,0],[4,3,2],[6,1,8]]
    print kmeans(pts,3)

モジュールロード

>>> import kmeans
>>> import inspect

どんな関数があったかなぁというのは、まぁdirでわかる

>>> dir(kmeans)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', \
'centroid', 'closest', 'distance', 'euclid', 'fst', 'groupby', 'kmeans', \
'part', 'recluster', 'recluster_', 'snd', 'sqrt', 'zipWith']

引数どうだっけ?となったばあいにはgetargsつかえばいいけどコードオブジェクトを引数にとるのでfunc_codeを渡してる

>>> inspect.getargs(kmeans.distance.func_code)
Arguments(args=['a', 'b'], varargs=None, keywords=None)

distanceって何の距離計算してんだっけ(マンハッタン?ユークリッド?)ソースみたいなあってなったらgetsource

>>> inspect.getsource(kmeans.distance)
'def distance(a,b): \n    return sqrt(sum(zipWith(euclid,a,b)))\n'
>>> inspect.getsource(kmeans.euclid)
'euclid  = lambda x, y : (x-y)**2\n'

というわけでユークリッド距離で定義された距離でのK-meansのコードだということがわかる。

>>> inspect.getfile(kmeans.distance)
'kmeans.py'
>>> inspect.getabsfile(kmeans.distance)
'/Users/kzfm/python/kmeans.py'

getabsfileでファイルの場所探してemacsで開いて直接読んじゃうことのほうが多いかもしれんけど。

About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021