6.11. Reduksi

Sebuah reduksi menciutkan array sepanjang satu atau lebih sumbu dengan cara menjumlahkan, merata-ratakan, mengambil nilai minimum, dan sebagainya. Setiap reduksi adalah satu panggilan library terhadap seluruh array, jauh lebih cepat dibanding loop Python yang setara. numpy mencakup operasi yang paling umum digunakan:

  • sum() -- total semua elemen

  • mean() -- rata-rata aritmetik (jumlah dibagi jumlah elemen)

  • std() -- standar deviasi, ddof= menyesuaikan pembagi (N - ddof)

  • min() / max() -- elemen terkecil dan terbesar

  • median() -- nilai tengah ketika elemen diurutkan (persentil ke-50)

  • argmin() / argmax() -- indeks dari elemen minimum atau maksimum

  • all() / any() -- reduksi nilai kebenaran pada array boolean

6.11.1. Tanpa kata kunci axis

Dipanggil tanpa axis=, sebuah reduksi mengembalikan skalar yang mencakup seluruh array:

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. Dengan kata kunci axis

axis= menciutkan satu sumbu yang ditentukan dan membiarkan sumbu lainnya tetap utuh. Hasilnya adalah array dengan peringkat satu tingkat lebih rendah dari input:

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

Aturan bentuk yang sama berlaku untuk setiap reduksi: axis=0 menciutkan sumbu pertama, axis=1 menciutkan sumbu kedua, dan seterusnya. Rata-rata / standar deviasi sepanjang sebuah baris, misalnya, ditulis sebagai np.mean(m, axis=1) dan np.std(m, axis=1). Hasilnya memiliki panjang sumbu lainnya.

Kata kunci keepdims=True mempertahankan sumbu yang diciutkan dengan panjang 1 alih-alih menghilangkannya. Perbedaan ini penting ketika hasil reduksi perlu di-broadcast kembali terhadap array aslinya: keepdims mempertahankan peringkat, yang menjaga aturan broadcasting selaras sumbu demi sumbu.

Pengurangan rata-rata setiap baris dari baris tersebut adalah penggunaan yang paling umum:

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

Tanpa keepdims, np.mean(m, axis=1) mengembalikan hasil 1-D dengan bentuk (3,). Broadcasting (3, 4) - (3,) menyejajarkan (3,) sebagai (1, 3) setelah penambahan peringkat, yang tidak kompatibel dengan (3, 4): sumbu terakhir tidak sesuai (4 terhadap 3) dan tidak ada yang bernilai 1, sehingga numpy mengangkat ValueError. keepdims=True adalah yang membuat pengurangan tetap valid.

6.11.3. Tata letak mempengaruhi performa

Dikombinasikan dengan tata letak row-major yang dibahas di Shape dan strides, mereduksi sepanjang sumbu terakhir adalah kasus yang paling murah. Reduksi menelusuri blok data ke arah penyimpanannya, tanpa lompatan dari baris ke baris:

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

Ketika aplikasi memiliki pilihan tentang cara menata layout sebuah buffer, letakkan sumbu yang panjang di posisi terakhir agar reduksi sepanjangnya berjalan ke arah yang cepat.

6.11.4. Iterable sebagai input

Sebagian besar reduksi menerima Python iterable (sebuah list, sebuah range, sebuah tuple) sebagai pengganti ndarray. Kemudahan ini membutuhkan beberapa mikrodetik untuk konversi implisit -- yang bertambah cepat di dalam loop. Ketika data yang sama direduksi beberapa kali, bangun ndarray sekali dan teruskan ke mana pun diperlukan.