Modulok és matematikai csomagok

Modulok használata

Egy Python modul nem más mint függvények és osztályok összessége, amelyet egy csomagban kapunk meg. Természetesen mi magunk is tudunk (egyelőre Python nyelven) írni modulokat, amelyeket mások aztán használhatnak.

Ha telepítettük a Pythont, a bépített modulokat is megkapjuk. Ezeket egyszerűen tudjuk importálni, sőt sokat közülük már használtunk is.

In [ ]:
import sys
print sys.path

A sys egy beépített modul, a rendszerrel kapcsolatos információkat tudjuk lekérdezni és használni (pl. parancssori argumentumok). Fent a sys.path változót irattuk ki. Ez azért lényeges, mert az import valami sor végrehajtásakor a Python a valami nevű modult először a beépített modulok között keresi, majd egy valami.py nevű fájlt keres a sys.path helyek egyikén. A sys.path akár változtatható is.

Importálni lehet egy egész fájlt is, egy könyvtárat, a benne lévő fájlokkal, vagy akár egyetlen függvényt is.

In [ ]:
from csv import reader
from itertools import permutations
for p in permutations(['A','B','C']):
    print p

Relatív import. Importálhatunk fájlokat abból a könyvtárból, ahol éppen vagyunk.

In [ ]:
from square import hello
hello()

numpy alapok

A numpy numerikus számításokra tervezett Python modul. Ha otthon szeretnénk használni, akkor az Anaconda telepítése után rendelkezésre áll. Telepítés után keressünk egy szimpatikus mappát, ahova dolgozni szeretnénk, majd adjuk ki a jupyter notebook parancsot a Windows command line-ban.

Először beimportáljuk a modult. Érdemes import numpy as np módon használni, hiszen ilyenkor nem kell minden alkalommal kiírni, hogy numpy, elég az np is.

In [ ]:
sys.path.append('d:\\numpy-1.11.0')

A numpy legfontosabb összetevője az array. Ez olyan, mintha egy Python lista lenne szteroidokon. Nézzük meg, hogyan működik!

In [ ]:
import numpy as np
x = np.arange(1,-1,-0.1)
y = np.array([[1,2,3],[1,2,4]])
In [ ]:
print x.dtype
print y.dtype
print x.shape
print y.shape
print x.ndim
print y.ndim
print x
print y

A numpy.array típusú változókon végezhetünk műveleteket, sőt, az alapműveletek többsége működik, de az ökölszabály az, hogy elemenként értelmezzük őket.

In [ ]:
a = np.array( [20,30,40,50] )
b = np.arange( 4 )
print a+b
print a-b
print b / (b+1.0)

Hasonlóan lista és egy elem között is értelmezzük az alapműveleteket. Ilyenkor a lista minden elemére elvégezzük a műveleteket és az eredmény ez a lista.

In [ ]:
b = np.arange(10)
print b
print b ** 2
print b + 10
print b % 3 == 1

Az előzőekből szinte kikövetkeztethető, hogy a mátrixszorzás sem a * művelettel történik.

In [ ]:
A=np.arange(2,6).reshape(2,2)
B=np.arange(3,-1,-1).reshape(2,2)
print A
print B
print A*B
print A.dot(B)

Első észrevétel a reshape használatához kapcsolódik. A (4,1) alakú array-ből (2,2) alakút tudunk csinálni. A dot bármikor hívható, ha a bal oldal szorozható a jobb oldallal.

Természetesen az indexelés is kényelmes. Először is megjegyezzük, hogy a klasszikus Python indexelés működik.

In [ ]:
x = np.arange(15).reshape(3,5)
print x
print x[0:2]

Sőt, indexelhetünk oszlopszinten is.

In [ ]:
print x[:,3]
print x[2,:3]

Megadhatunk indexek listáját is.

In [ ]:
a = np.arange(12)**2
i = np.array( [ 1,1,3,8,5 ] ) 
print a[i]

Függvényeket is hívhatunk elemenként. Sőt, a listaműveletek is elérhetők, persze np előtaggal, hiszen array típusra a normál Python függvények nem működnek. Átlagot, szórást is egy sorban számolhatunk.

In [ ]:
x = np.log(np.arange(2,10,0.5))
print x
print x.sum()
print x.mean()
print x.std()

Amit még tud a numpy. Működik a zeros és a ones. Az identitásmátrix az eye mögött rejtőzik.

In [ ]:
print np.zeros([4,3])
print np.ones([4,1])
print np.eye(4)

Véletlen számokat, sőt véletlen vektorokat is generálhatunk.

In [ ]:
np.random.rand(3,4)

Plot

Függvények ábrázolására a matplotlib csomagot használjuk.

In [ ]:
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt

Először egy egyszerű plot.

In [ ]:
plt.plot([1,2,4])
plt.ylabel('some numbers')
plt.show()

Látjuk, hogy nem szinbolikusan számol, hanem egyszerűen összeköti a számokat vonalakkal. Szinuszgörbét is hasonlóan rajzolunk. Az np.sin a lista minden elemére számol szinuszt.

In [ ]:
plt.plot(np.arange(0,2*np.pi,0.05), np.sin(np.arange(0,2*np.pi,0.05)), 'g')
plt.axis([0,2*np.pi,-1,1])
plt.show()

És a végére egy kis Monte-Carlo. Generálunk véletlen pontokat a $[-2,2]\times[0,1]$ téglában. Először is, véletlen számokat csak 0 és 1 között tudunk generálni, de egy kis transzformáció nem árt senkinek. A J tömbben azon $(x,y)$ pontok indexeit tároljuk, ahol $e^{-x^2} > y$. Mivel a téglalap területe 4, az ilyen pontok aránya az teljes populáción belül, néggyel szorozva egy közelítést ad $\int_{-2}^2e^{-x^2}\,\mathrm{d}x$-re.

In [ ]:
X = np.random.rand(500000,2)
X[:,0] = X[:,0]*4-2
J = np.where(X[:,1] < np.exp(-X[:,0]**2))[0]
print len(J) / 500000.0 * 4

Nézzük meg rajzon.

In [ ]:
Xp = X[:2000]
Ip = [i for i in range(2000) if i in J]
Inp = [i for i in range(2000) if i not in J]
plt.plot(Xp[Ip,0],Xp[Ip,1], 'bd', Xp[Inp,0],Xp[Inp,1], 'rd')
plt.show()
In [ ]: