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 elemenmean()-- rata-rata aritmetik (jumlah dibagi jumlah elemen)std()-- standar deviasi,ddof=menyesuaikan pembagi (N - ddof)median()-- nilai tengah ketika elemen diurutkan (persentil ke-50)argmin()/argmax()-- indeks dari elemen minimum atau maksimum
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.