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.