CHEM-A2600 - Kemiantekniikan ohjelmointikurssi, Luento-opetus, 22.4.2024-28.6.2024
Kurssiasetusten perusteella kurssi on päättynyt 28.06.2024 Etsi kursseja: CHEM-A2600
Python-oppimateriaali (CHEM-A2600)
Laskuoperaatiot NumPy-taulukoilla
Luodaan ensin uusi taulukko (yksiulotteinen vektori):
import numpy as np v1 = np.arange(100, 1001, 100) # v1 on array([ 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000])
NumPy-taulukoiden ja yksittäisten lukuarvojen laskuoperaatiot onnistuvat suoraviivaisesti. NumPy suorittaa laskuoperaation jokaiselle alkiolle:
v2 = v1 + 1 # array([ 101, 201, 301, 401, 501, 601, 701, 801, 901, 1001]) v3 = v1 * 2 # array([ 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) v4 = v1 / 100 # array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]) v42 = 100 / v1 # array([ 1., 0.5, 0.33333333, 0.25, 0.2, 0.16666667, 0.14285714, 0.125, 0.11111111, 0.1])
NumPy-taulukoita voi myos lisätä, kertoa ja jakaa keskenään. Operaatiot tehdaan alkioittain, joten taulukoiden tulee olla samankokoisia!
v5 = v2 + v2 # array([ 202, 402, 602, 802, 1002, 1202, 1402, 1602, 1802, 2002]) v6 = v4 * v4 # array([ 1., 4., 9., 16., 25., 36., 49., 64., 81., 100.]) v7 = v3 / v1 # array([ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.])
Seuraavassa esimerkissä matriisin M sarakkeiden määrä (4) täsmää vektorin a pituuden (4) kanssa. Jokainen rivivektori kerrotaan alkioittain vektorilla a:
M = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) a = np.array([1, 2, 3, 4]) tulo = M * a # Ensimmäinen rivi on siis [1*1, 2*2, 3*3, 4*4] # array([[ 1, 4, 9, 16], # [ 5, 12, 21, 32], # [ 9, 20, 33, 48]])
Huomaa, että esimerkin kertolasku M * a on aivan eri asia kuin oikea matriisitulo! Siitä lisää seuraavassa luvussa.
Laskutoimitukset ilman silmukoita
Tarkastellaan esimerkin avulla, kuinka NumPy-taulukoiden kanssa toimitaan listoihin verrattuna. Aiemmin olemme oppineet, kuinka kahdesta listasta lasketaan tuloksia kolmanteen:
massat = [2.2, 4.1, 5.6, 1.2, 6.7] moolimassat = [18.015, 58.44, 74.55, 81.408, 144.645] ainemaarat = [] for massa, moolimassa in zip(massat, moolimassat): ainemaarat.append(massa / moolimassa)
NumPyllä for-silmukkaa ei tarvita:
import numpy as np massat = np.array([2.2, 4.1, 5.6, 1.2, 6.7]) moolimassat = np.array([18.015, 58.44, 74.55, 81.408, 144.645]) ainemaarat_np = massat / moolimassat
NumPy jakaa siis taulukon massat jokaisen alkion taulukon moolimassat vastaavalla alkiolla ja lopputulos on uusi taulukko ainemaarat.
Molemmissa tapauksissa lasketut ainemäärät ovat samat. Mutta Numpyn tapa on merkittävästi nopeampi, varsinkin kun kyseessä on vähänkin isompi datamäärä. NumPyn lähestymistapaa kutsutaan vektoroinniksi.
Laajempi esimerkki
Toteutetaan funktio ainemaara NumPy-taulukoiden avulla:
import numpy as np def ainemaara(m, M): # m, M: massa (g) ja moolimassa (g/mol) # Kukin parametri voi olla joko NumPy-taulukko tai yksittäinen luku # Oletetaan, että kaikki parametrit ovat kelvollisia lukuarvoja # Paluuarvo: ainemäärä(t) # Jos yksikin parametri on NumPy-taulukko, paluuarvo on NumPy-taulukko return m / M # Luodaan kolmen alkiota sisältävät taulukot massoista ja moolimassoista massat = np.array([3.2, 0.5, 2.2]) moolimassat = np.array([58.44, 42.394, 120.921]) # NaCl LiCl RbCl # Lasketaan ja tulostetaan ainemäärät. Funktio palauttaa taulukon. n1 = ainemaara(massat, moolimassat) print(n1) # Funktio toimii myös yksittäisillä lukuarvoilla # Tässä tapauksessa funktio palauttaa yksittäisen liukuluvun n2 = ainemaara(3.2, 58.44) print(n2) # Funktio toimii myös jos toinen parametri on yksittäinen luku ja toinen taulukko # Tässä tapauksessa funktio palauttaa taulukon n3 = ainemaara(3.2, moolimassat) print(n3)
tulostaa
[0.05475702 0.01179412 0.0181937 ]
0.05475701574264203
[0.05475702 0.07548238 0.02646356]
Tehtävä 4.4.1