6.11. Pelkistykset¶
Pelkistys tiivistää taulukon yhden tai useamman akselin suuntaisesti summaamalla, laskemalla keskiarvon, ottamalla minimin ja niin edelleen. Jokainen pelkistys on yksittäinen kirjastokutsu koko taulukolle, paljon nopeampi kuin vastaava Python-silmukka. numpy kattaa jokapäiväiset pelkistykset:
sum()– kaikkien alkioiden summamean()– aritmeettinen keskiarvo (summa jaettuna alkioiden lukumäärällä)std()– keskihajonta,ddof=säätää jakajaa (N - ddof)median()– keskimmäinen arvo, kun alkiot on lajiteltu (50. persentiili)argmin()/argmax()– pienimmän tai suurimman alkion indeksi
6.11.1. Ilman axis-avainsanaa¶
Ilman axis=-avainsanaa kutsuttuna pelkistys palauttaa skalaarin, joka kattaa koko taulukon:
a = np.array([1, 2, 3, 4], dtype=np.float)
np.sum(a) # 10.0
np.mean(a) # 2.5
np.std(a) # 1.118...
np.median(a) # 2.5
b = np.array([40, 10, 30, 20], dtype=np.float)
np.max(b) # 40.0
np.argmax(b) # 0 (index of the maximum)
6.11.2. axis-avainsanan kanssa¶
axis= kutistaa yhden nimetyn akselin ja jättää muut ennalleen. Tulos on taulukko, jonka kertaluku on yhtä pienempi kuin syötteen:
m = np.arange(12, dtype=np.float).reshape((3, 4))
np.sum(m) # 66.0 - scalar
np.sum(m, axis=0) # length-4 - column sums
np.sum(m, axis=1) # length-3 - row sums
Sama muotosääntö pätee jokaiseen pelkistykseen: axis=0 kutistaa ensimmäisen akselin, axis=1 kutistaa toisen ja niin edelleen. Esimerkiksi rivin suuntainen keskiarvo / keskihajonta kirjoitetaan np.mean(m, axis=1) ja np.std(m, axis=1). Tuloksen pituus vastaa toisen akselin pituutta.
keepdims=True-avainsana säilyttää kutistetun akselin paikallaan pituudella 1 sen poistamisen sijaan. Erolla on merkitystä, kun pelkistetyn tuloksen täytyy lähettää (broadcast) takaisin alkuperäistä vastaan: keepdims säilyttää kertaluvun, mikä pitää lähetyssäännöt linjassa akseli akselilta.
Kunkin rivin keskiarvon vähentäminen kyseiseltä riviltä on tyypillinen käyttötapa:
m = np.arange(12, dtype=np.float).reshape((3, 4))
row_means = np.mean(m, axis=1, keepdims=True)
# row_means has shape (3, 1)
centred = m - row_means
# (3, 4) - (3, 1) -> (3, 4), each row centred on its own mean
Ilman keepdims-avainsanaa np.mean(m, axis=1) palauttaa 1-ulotteisen tuloksen, jonka muoto on (3,). Lähetys (3, 4) - (3,) asettaa muodon (3,) muotoon (1, 3) kertaluvun etuliitteen lisäämisen jälkeen, mikä on yhteensopimaton muodon (3, 4) kanssa: viimeiset akselit ovat ristiriidassa (4 vastaan 3) eikä kumpikaan ole 1, joten numpy nostaa poikkeuksen ValueError. keepdims=True on se, mikä pitää vähennyksen kelvollisena.
6.11.3. Sijoittelulla on merkitystä¶
Yhdessä rivijärjestyksen kanssa, joka käsiteltiin sivulla Muoto ja askelvälit, viimeisen akselin suuntainen pelkistys on edullisin tapaus. Pelkistys kulkee datalohkon läpi siihen suuntaan, johon se on tallennettu, ilman hyppyjä rivistä toiseen:
m = np.arange(2000, dtype=np.float).reshape((2, 1000))
np.sum(m, axis=1) # cheap - long axis is the inner one
np.sum(m, axis=0) # has to jump rows on every step
Kun sovellus voi vaikuttaa siihen, miten puskuri sijoitetaan muistiin, laita pitkä akseli viimeiseksi, jotta sen suuntaiset pelkistykset toimivat nopeaan suuntaan.
6.11.4. Iteroitavat syötteenä¶
Useimmat pelkistykset hyväksyvät Python-iteroitavan (list, range, monikko) ndarray-olion sijaan. Tämä mukavuus maksaa muutaman mikrosekunnin implisiittisestä muunnoksesta – mikä kertyy nopeasti silmukassa. Kun samaa dataa pelkistetään useita kertoja, rakenna ndarray kerran ja välitä se eteenpäin.