Di artikel sebelumnya dari seri ini “Menulis Kode Python yang Efisien. Mendefinisikan & Mengukur Efisiensi Kode” Saya membahas apa itu kode efisien python dan bagaimana menggunakan berbagai struktur data, fungsi, dan modul bawaan Python untuk menulis kode yang lebih bersih, lebih cepat, dan lebih efisien. Saya juga menjelajahi cara mengatur waktu dan kode profil untuk menemukan kemacetan
Tulis Kode Python yang Efisien. Mendefinisikan & Mengukur Efisiensi Kode
Pelajari cara mengukur efisiensi kode Python Anda
sedang. com
Pada artikel ini, kita akan berlatih menghilangkan kemacetan ini, dan pola desain buruk lainnya, menggunakan pustaka Python yang paling banyak digunakan oleh ilmuwan data. NumPy, dan panda
Foto oleh Alessandro Bianchi di Unsplash
Daftar Isi
- Membuat Kode Anda Efisien
1. 1. Menggabungkan, Menghitung, dan Iterasi Secara Efisien
1. 2. Pengantar Teori Himpunan
1. 3. Menghilangkan Loop
1. 4. Menulis Loop Lebih Baik - Pengantar Optimasi Panda
2. 1. Iterasi DataFrame Pandas
2. 2. Alternatif Panda untuk Looping
2. 3. Iterasi Panda yang Optimal - Referensi
Semua kode dan kumpulan data yang digunakan dalam artikel ini dapat ditemukan di repositori GitHub ini
GitHub - youssefHosni/Advanced-Python-Programming-Tutorials-
Anda tidak dapat melakukan tindakan tersebut saat ini. Anda masuk dengan tab atau jendela lain. Anda keluar di tab lain atau…
github. com
Jika Anda ingin mempelajari Ilmu Data dan Pembelajaran Mesin secara gratis, lihat sumber daya ini
- Peta jalan interaktif gratis untuk mempelajari Ilmu Data dan Pembelajaran Mesin sendiri. Mulai di sini. https. //petugas. co/belajar/peta jalan/intro
- Mesin pencari sumber belajar Data Science (GRATIS). Tandai sumber daya favorit Anda, tandai artikel sebagai selesai dan tambahkan catatan belajar. https. //petugas. bersama/belajar
- Ingin belajar Ilmu Data dari nol dengan dukungan mentor dan komunitas belajar? . https. //masyarakat. agen. co/spasi/9010170/
Jika Anda ingin memulai karir di bidang ilmu data & AI dan Anda tidak tahu caranya. Saya menawarkan sesi mentoring ilmu data dan mentoring karir jangka panjang
- Pendampingan jangka panjang. https. //lnkd. di/dtdUYBrM
- Sesi mentoring. https. //lnkd. di/dXeg3KPW
Bergabunglah dengan program keanggotaan Medium hanya dengan $5 untuk terus belajar tanpa batas. Saya akan menerima sebagian kecil dari biaya keanggotaan Anda jika Anda menggunakan tautan berikut, tanpa biaya tambahan untuk Anda
1. Membuat Kode Anda Efisien
Pada bagian ini, kita akan membahas lebih banyak tips dan trik efisiensi. Anda akan mempelajari beberapa modul bawaan yang berguna untuk menulis kode yang efisien dan berlatih menggunakan teori himpunan. Anda kemudian akan belajar tentang pola perulangan di Python dan cara membuatnya lebih efisien
1. 1. Menggabungkan, Menghitung, dan Iterasi Secara Efisien
Menggabungkan Objek
Dalam subbagian ini, kita akan membahas menggabungkan, menghitung, dan mengulangi objek secara efisien dengan python. Misalkan kita memiliki dua daftar. salah satu nama dan yang lainnya adalah usia masing-masing. Kami ingin menggabungkan daftar ini sehingga setiap nama disimpan di samping umurnya. Kita dapat mengulangi daftar nama menggunakan menghitung dan mengambil usia yang sesuai dari setiap nama menggunakan variabel indeks
Tapi zip fungsi bawaan Python memberikan solusi yang lebih elegan. Nama "zip" menjelaskan bagaimana fungsi ini menggabungkan objek seperti ritsleting pada jaket (membuat dua hal yang terpisah menjadi satu). zip mengembalikan objek zip yang harus dibongkar ke dalam daftar dan dicetak untuk melihat isinya. Setiap item adalah kumpulan elemen dari daftar asli
Python juga dilengkapi dengan sejumlah modul bawaan yang efisien. Modul koleksi berisi tipe data khusus yang dapat digunakan sebagai alternatif untuk kamus standar, daftar, set, dan tupel. Beberapa tipe data khusus yang terkenal adalah
- nametuple. tuple subclass dengan bidang bernama
- deque. wadah seperti daftar dengan penambahan dan pop cepat
- Menangkal. dict untuk menghitung objek hashable
- DipesanDict. dict yang mempertahankan urutan entri
- defaultdict. dict yang memanggil fungsi pabrik untuk memasok nilai yang hilang
Menghitung Objek
Mari gali lebih dalam objek Counter. Pertama, kita akan mengunggah dataset pokemon dan mencetak lima baris pertama kemudian kita akan menghitung jumlah pokemon per jenis menggunakan for loop dan kemudian menggunakan fungsi Counter
- Mari muat dataset pokemon dan cetak lima baris pertama
- Sekarang kita akan menghitung jumlah pokemon per masing-masing jenis menggunakan loop dan menghitung waktu eksekusi
- Terakhir, kami akan menghitung jumlah pokemon per masing-masing jenis menggunakan fungsi Penghitung dan membandingkan waktunya
Kita dapat melihat bahwa menggunakan fungsi Penghitung dari modul koleksi adalah pendekatan yang lebih efisien. Cukup impor Penghitung dan berikan objek yang akan dihitung. Tidak perlu satu putaran. Penghitung mengembalikan kamus Penghitung dari pasangan kunci-nilai. Saat dicetak, ini diurutkan berdasarkan jumlah tertinggi hingga terendah. Jika membandingkan waktu proses, kami akan melihat bahwa menggunakan Penghitung membutuhkan waktu lebih sedikit dibandingkan dengan pendekatan kamus standar
itertools
Modul bawaan lainnya, itertools, berisi alat fungsional untuk bekerja dengan iterator. Subset dari alat ini adalah
- Iterator tak terbatas. menghitung, siklus, ulangi
- Iterator terbatas. terakumulasi, berantai, zip_longest, dll
- Generator kombinasi. perkalian, permutasi, kombinasi
Kami akan fokus pada generator kombinatorik. Generator ini secara efisien menghasilkan produk Cartesian, permutasi, dan kombinasi objek. Mari jelajahi sebuah contoh
Kombinasi
Misalkan kita ingin mengumpulkan semua pasangan kombinasi tipe Pokemon yang mungkin. Kita bisa melakukan ini dengan loop for bersarang yang mengulang daftar poke_types dua kali. Perhatikan bahwa pernyataan bersyarat digunakan untuk melewati pasangan yang memiliki tipe yang sama dua kali. Misalnya, jika x adalah 'Bug' dan y adalah 'Bug', kami ingin melewatkan pasangan ini. Karena kami tertarik pada kombinasi (di mana urutan tidak penting), pernyataan lain digunakan untuk memastikan salah satu urutan dari pasangan belum ada dalam daftar kombo sebelum menambahkannya. Misalnya, pasangan ('Bug', 'Fire') sama dengan pasangan ('Fire', 'Bug'). Kami menginginkan salah satu dari pasangan ini, bukan keduanya
Generator kombinasi dari itertools memberikan solusi yang lebih efisien. Pertama, kami mengimpor kombinasi dan kemudian membuat objek kombinasi dengan memberikan daftar poke_types dan panjang kombinasi yang kami inginkan. Kombinasi mengembalikan objek kombinasi, yang kami buka ke dalam daftar dan cetak untuk melihat hasilnya. Jika membandingkan runtime, kami akan melihat penggunaan kombinasi jauh lebih cepat daripada loop bersarang
1. 2. Pengantar Teori Himpunan
Seringkali, kami ingin membandingkan dua objek untuk mengamati persamaan dan perbedaan antara isinya. Saat melakukan jenis perbandingan ini, yang terbaik adalah memanfaatkan cabang matematika yang disebut teori himpunan. Seperti yang Anda ketahui, Python hadir dengan tipe data set bawaan. Set datang dengan beberapa metode praktis yang dapat kita gunakan untuk membandingkan seperti
- persimpangan(). semua elemen yang ada di kedua himpunan
- perbedaan(). semua elemen dalam satu set tapi tidak yang lain
- symmetric_difference(). semua elemen dalam tepat satu himpunan
- Persatuan(). semua elemen yang ada di salah satu himpunan
Saat kami ingin membandingkan objek berkali-kali dan dengan cara yang berbeda, kami harus mempertimbangkan untuk menyimpan data kami dalam kumpulan untuk menggunakan metode efisien ini. Fitur bagus lainnya dari set Python adalah kemampuannya untuk dengan cepat memeriksa apakah ada nilai di dalam anggotanya. Kami menyebutnya pengujian keanggotaan menggunakan operator in. Kami akan membahas bagaimana menggunakan operator in dengan set jauh lebih cepat daripada menggunakannya dengan daftar atau tuple
Misalkan kita memiliki dua daftar nama Pokemon. list_a dan list_b dan kami ingin membandingkan daftar ini untuk melihat Pokemon mana yang muncul di kedua daftar. Pertama-tama kita dapat menggunakan perulangan for bersarang untuk membandingkan setiap item di list_a dengan setiap item di list_b dan hanya mengumpulkan item yang muncul di kedua daftar. Namun, mengulangi setiap item di kedua daftar sangat tidak efisien
Namun, cara yang lebih baik adalah menggunakan tipe data set Python untuk membandingkan daftar ini. Dengan mengonversi setiap daftar menjadi satu set, kita dapat menggunakan metode titik-temu untuk mengumpulkan Pokemon yang dibagikan di antara dua set. Satu baris kode sederhana dan tidak perlu loop
Kami mendapat jawaban yang sama dengan jumlah baris kode yang jauh lebih sedikit, kami juga dapat membandingkan runtime untuk melihat seberapa banyak menggunakan set jauh lebih cepat daripada menggunakan loop
Kita dapat melihat bahwa menggunakan set jauh lebih cepat daripada menggunakan for loop. Kita juga bisa menggunakan metode set untuk melihat Pokemon yang ada di satu set tetapi tidak di set lainnya. Untuk mengumpulkan Pokemon yang ada di set_a tetapi tidak ada di set_b, gunakan set_a. perbedaan(set_b)
Jika kita menginginkan Pokemon di set_b, tetapi tidak di set_a, kita menggunakan set_b. perbedaan(set_a)
Untuk mengumpulkan Pokemon yang ada di salah satu set (tetapi tidak keduanya), kita dapat menggunakan metode yang disebut perbedaan simetris
Terakhir, kita dapat menggabungkan set ini menggunakan. metode serikat. Ini mengumpulkan semua Pokemon unik yang muncul di salah satu atau kedua set
Keuntungan efisiensi bagus lainnya saat menggunakan set adalah kemampuan untuk dengan cepat memeriksa apakah item tertentu adalah anggota dari elemen set. Pertimbangkan koleksi 720 nama Pokémon kami yang disimpan sebagai daftar, tuple, dan set
Kami ingin memeriksa apakah karakter, Zubat, ada di setiap struktur data ini dan mencetak waktu eksekusi untuk setiap tipe data
Saat membandingkan runtime, jelas bahwa pengujian keanggotaan dengan set jauh lebih cepat daripada daftar atau tuple
Satu keuntungan efisiensi akhir saat menggunakan set berasal dari definisi set itu sendiri. Himpunan didefinisikan sebagai kumpulan elemen yang berbeda. Dengan demikian, kita dapat menggunakan satu set untuk mengumpulkan item unik dari objek yang ada. Mari tentukan daftar primary_types, yang berisi tipe utama dari setiap Pokémon. Jika kami ingin mengumpulkan tipe Pokémon unik dalam daftar ini, kami dapat menulis loop for untuk mengulangi daftar, dan hanya menambahkan tipe Pokémon yang belum ditambahkan ke daftar unique_types
Menggunakan satu set membuat ini lebih mudah. Yang harus kita lakukan adalah mengubah daftar primary_types menjadi satu set, dan kita punya solusinya. satu set jenis Pokemon yang berbeda
1. 3. Menghilangkan Loop
Meskipun menggunakan perulangan saat menulis kode Python belum tentu merupakan pola desain yang buruk, menggunakan perulangan asing bisa menjadi tidak efisien dan mahal. Mari jelajahi beberapa alat yang dapat membantu kita menghilangkan kebutuhan untuk menggunakan perulangan dalam kode kita. Python hadir dengan beberapa pola perulangan yang dapat digunakan saat kita ingin mengulangi konten objek
- Untuk loop ulangi elemen urutan bagian demi bagian
- While loop mengeksekusi loop berulang kali selama beberapa kondisi Boolean terpenuhi
- Loop bersarang menggunakan banyak loop di dalam satu sama lain
Meskipun semua pola perulangan ini didukung oleh Python, kita harus berhati-hati saat menggunakannya. Karena sebagian besar loop dievaluasi secara sepotong demi sepotong, seringkali merupakan solusi yang tidak efisien
Kita harus mencoba menghindari perulangan sebanyak mungkin saat menulis kode yang efisien. Menghilangkan perulangan biasanya menghasilkan lebih sedikit baris kode yang lebih mudah ditafsirkan. Salah satu idiom kode pythonic adalah “datar lebih baik daripada bersarang. ” Berjuang untuk menghilangkan loop dalam kode kita akan membantu kita mengikuti idiom ini
Misalkan kita memiliki daftar daftar, yang disebut poke_stats, yang berisi nilai statistik untuk setiap Pokémon. Setiap baris sesuai dengan Pokémon, dan setiap kolom sesuai dengan nilai statistik spesifik Pokémon. Di sini, kolom mewakili Poin Kesehatan, Serangan, Pertahanan, dan Kecepatan Pokémon. Kami ingin melakukan penjumlahan sederhana dari setiap baris ini untuk mengumpulkan statistik total untuk setiap Pokémon. Jika kita menggunakan loop untuk menghitung jumlah baris, kita harus mengulangi setiap baris dan menambahkan jumlah baris ke daftar total. Kita dapat menyelesaikan tugas yang sama, dalam baris kode yang lebih sedikit, dengan pemahaman daftar. Atau, kita bisa menggunakan fungsi peta bawaan yang sudah kita bahas sebelumnya di artikel sebelumnya
Masing-masing pendekatan ini akan mengembalikan daftar yang sama, tetapi menggunakan pemahaman daftar atau fungsi map membutuhkan satu baris kode, dan memiliki runtime yang lebih cepat
Kami juga telah membahas beberapa modul bawaan yang dapat membantu kami menghilangkan pengulangan di artikel sebelumnya. Alih-alih menggunakan loop for bersarang, kita dapat menggunakan kombinasi dari modul itertools untuk solusi yang lebih bersih dan lebih efisien
Teknik ampuh lainnya untuk menghilangkan loop adalah dengan menggunakan paket NumPy. Misalkan kita memiliki kumpulan statistik yang sama dengan yang kita gunakan pada contoh sebelumnya tetapi disimpan dalam larik NumPy alih-alih daftar daftar
Kami ingin mengumpulkan nilai stat rata-rata untuk setiap Pokémon (atau baris) dalam larik kami. Kita bisa menggunakan loop untuk mengulangi array dan mengumpulkan rata-rata baris
Hilangkan Loops dengan NumPy
Tapi, array NumPy memungkinkan kita melakukan perhitungan pada seluruh array sekaligus. Di sini, kami menggunakan metode dot-mean dan menentukan sumbu sama dengan 1 untuk menghitung rata-rata untuk setiap baris (artinya kami menghitung rata-rata nilai kolom). Ini menghilangkan kebutuhan akan loop dan jauh lebih efisien
Saat membandingkan runtime, kita melihat bahwa menggunakan metode dot-mean pada seluruh larik dan menentukan sumbu jauh lebih cepat daripada menggunakan loop
1. 4. Menulis Loop Lebih Baik
Kami telah membahas bagaimana loop bisa mahal dan tidak efisien. Tapi, terkadang Anda tidak bisa menghilangkan loop. Di bagian ini, kita akan mempelajari cara membuat perulangan lebih efisien saat perulangan tidak dapat dihindari. Sebelum menyelam, beberapa loop yang akan kita diskusikan dapat dihilangkan dengan menggunakan teknik yang tercakup dalam pelajaran sebelumnya. Untuk tujuan demonstratif, kami akan menganggap kasus penggunaan yang ditampilkan di sini adalah contoh di mana perulangan tidak dapat dihindari
Cara terbaik untuk membuat loop lebih efisien adalah dengan menganalisis apa yang sedang dilakukan dalam loop. Kami ingin memastikan bahwa kami tidak melakukan pekerjaan yang tidak perlu di setiap iterasi. Jika perhitungan dilakukan untuk setiap iterasi dari sebuah loop, tetapi nilainya tidak berubah dengan setiap iterasi, sebaiknya pindahkan perhitungan ini ke luar (atau di atas) loop. Jika sebuah loop mengonversi tipe data dengan setiap iterasi, kemungkinan konversi ini dapat dilakukan di luar (atau di bawah) loop menggunakan fungsi peta. Apa pun yang dapat dilakukan sekali harus dipindahkan ke luar lingkaran. Mari jelajahi beberapa contoh
Memindahkan perhitungan di atas satu lingkaran
Kami memiliki daftar nama Pokemon dan susunan nilai serangan yang sesuai dari setiap Pokemon. Kami ingin mencetak nama setiap Pokémon dengan nilai serangan yang lebih besar dari rata-rata semua nilai serangan. Untuk melakukan ini, kami akan menggunakan loop yang berulang pada setiap Pokémon dan nilai serangannya. Untuk setiap iterasi, total rata-rata serangan dihitung dengan mencari nilai rata-rata dari semua serangan. Kemudian, nilai serangan setiap Pokémon dievaluasi untuk melihat apakah melebihi rata-rata total
Inefisiensi dalam loop ini adalah variabel total_attack_avg yang dibuat dengan setiap iterasi loop. Namun, perhitungan ini tidak berubah di antara iterasi karena merupakan rata-rata keseluruhan. Kita hanya perlu menghitung nilai ini satu kali. Dengan memindahkan perhitungan ini di luar (atau di atas) loop, kami menghitung rata-rata serangan total hanya sekali. Kami mendapatkan hasil yang sama, tetapi ini adalah pendekatan yang lebih efisien
Mari bandingkan runtime kedua metode
Kami melihat bahwa menjaga perhitungan total_attack_avg dalam loop membutuhkan waktu lebih dari 120 mikrodetik
konversi holistik
Cara lain untuk membuat perulangan lebih efisien adalah dengan menggunakan konversi holistik di luar (atau di bawah) perulangan. Dalam contoh di bawah ini kami memiliki tiga daftar dari 720 dataset Pokemon. daftar nama setiap Pokémon, daftar yang sesuai dengan apakah Pokémon memiliki status legendaris atau tidak, dan daftar generasi setiap Pokémon. Kami ingin menggabungkan objek-objek ini sehingga setiap nama, status, dan generasi disimpan dalam daftar tersendiri. Untuk melakukan ini, kami akan menggunakan loop yang mengulang output dari fungsi zip. Ingat, zip mengembalikan kumpulan tupel, jadi kita perlu mengonversi setiap tupel menjadi daftar karena kita ingin membuat daftar daftar sebagai output kita. Kemudian, kami menambahkan setiap poke_list individu ke variabel output poke_data kami. Dengan mencetak hasilnya, kami melihat daftar daftar yang kami inginkan
Namun, mengonversi setiap tuple menjadi daftar di dalam loop tidak terlalu efisien. Sebagai gantinya, kita harus mengumpulkan semua poke_tuple kita bersama-sama, dan menggunakan fungsi peta untuk mengonversi setiap tupel menjadi sebuah daftar. Loop tidak lagi mengonversi tupel menjadi daftar dengan setiap iterasi. Sebagai gantinya, kami memindahkan tuple ini ke daftar konversi di luar (atau di bawah) loop. Dengan begitu, kami mengonversi tipe data sekaligus (atau secara holistik) daripada mengonversi di setiap iterasi
Runtime menunjukkan bahwa mengonversi setiap tuple ke daftar di luar loop lebih efisien
2. Pengantar Optimasi Panda
2. 1. Iterasi DataFrame Pandas
Pandas adalah library yang digunakan untuk analisis data. Konstruk utama panda adalah DataFrame, struktur data tabular dengan baris dan kolom berlabel. Kami akan fokus pada pendekatan terbaik untuk iterasi melalui DataFrame. Mari kita mulai dengan menganalisis kumpulan data Major League Baseball. Ini berisi statistik tim untuk setiap tim Baseball Liga Utama dari tahun 1962 hingga 2012, yang disimpan dalam DataFrame panda bernama baseball_df
Kami akan fokus pada kolom W, yang menentukan jumlah kemenangan yang dimiliki tim dalam satu musim dan kolom G yang berisi jumlah pertandingan yang dimainkan tim dalam satu musim.
Menghitung dan Menambahkan persentase kemenangan
Salah satu statistik populer yang digunakan untuk mengevaluasi kinerja tim pada musim tertentu adalah persentase kemenangan tim. Metrik ini dihitung dengan membagi total kemenangan tim dengan jumlah permainan yang dimainkan. Berikut adalah fungsi sederhana untuk melakukan perhitungan ini
Sekarang kami ingin membuat kolom baru di Baseball_df DataFrame kami yang menyimpan persentase kemenangan masing-masing tim untuk satu musim. Untuk melakukan ini, kita perlu mengulangi baris DataFrame dan menerapkan fungsi calc_win_perc kita. Pertama, kami membuat win_perc_list kosong untuk menyimpan semua persentase kemenangan yang akan kami hitung. Kemudian, kami menulis sebuah loop yang akan mengulangi setiap baris DataFrame. Perhatikan bahwa kita menggunakan variabel indeks (i) yang berkisar dari nol hingga jumlah baris yang ada di dalam DataFrame. Kami kemudian menggunakan. metode iloc untuk mencari setiap baris dalam DataFrame menggunakan variabel indeks
Kemudian kami meraih kemenangan dan permainan masing-masing tim dengan merujuk pada kolom W dan G. Selanjutnya, kami meneruskan kemenangan tim dan permainan yang dimainkan ke calc_win_perc untuk menghitung persentase kemenangan. Terakhir, kami menambahkan win_perc ke win_perc_list dan melanjutkan pengulangan. Kami membuat kolom yang diinginkan di DataFrame, disebut WP, dengan menyetel nilai kolom sama dengan win_perc_list
Mengulangi DataFrame dengan. iloc memberi kami hasil yang kami inginkan, tetapi apakah itu tidak efisien. Saat memperkirakan runtime, file. Pendekatan iloc memakan waktu 660 milidetik, yang cukup tidak efisien
Iterasi dengan. iterrows()
panda datang dengan beberapa metode efisien untuk mengulang DataFrame. Metode pertama yang akan kita bahas adalah. metode iterrows. Ini mirip dengan. metode iloc, tapi. iterrows mengembalikan setiap baris DataFrame sebagai Tuple dari pasangan (indeks, Seri panda). Ini berarti setiap objek dikembalikan dari. iterrows berisi indeks setiap baris sebagai elemen pertama dan data di setiap baris sebagai Seri panda sebagai elemen kedua
Perhatikan bahwa kita masih membuat win_perc_list kosong, tetapi sekarang kita tidak perlu membuat variabel indeks untuk mencari setiap baris dalam DataFrame. . iterrows menangani pengindeksan untuk kita. Sisa perulangan for tetap sama untuk membuat kolom persentase kemenangan baru di dalam Bingkai Data baseball_df kita
Menggunakan. iterrows memakan waktu sekitar separuh waktu. iloc diperlukan untuk mengulangi DataFrame kami
Iterasi dengan. itertuples()
Panda juga datang dengan metode iterasi lain yang disebut. itertuples yang seringkali lebih efisien daripada. iterrows. Mari lanjutkan menggunakan kumpulan data baseball kita untuk membandingkan kedua metode ini. Misalkan kita memiliki DataFrame panda yang disebut team_wins_df yang berisi total kemenangan masing-masing tim dalam satu musim
Jika kita menggunakan. iterrows untuk mengulang dataFrame team_wins_df kami dan mencetak tupel setiap baris, kami melihat bahwa nilai setiap baris disimpan sebagai Seri panda. Ingat,. iterrows mengembalikan setiap baris DataFrame sebagai Tuple dari pasangan (indeks, Seri panda), jadi kita harus mengakses nilai baris dengan pengindeksan braket persegi
Tapi, kita bisa menggunakan. itertuples untuk mengulang baris DataFrame kami sebagai gantinya. Itu. metode itertuples mengembalikan setiap baris DataFrame sebagai tipe data khusus yang disebut namedtuple. Namedtuple adalah salah satu tipe data khusus yang ada di dalam modul koleksi yang telah kita bahas sebelumnya. Tipe data ini berperilaku seperti tuple Python tetapi memiliki bidang yang dapat diakses menggunakan pencarian atribut
Perhatikan dalam output bahwa setiap baris_namedtuple yang dicetak memiliki atribut Indeks dan setiap kolom dalam team_wins_df kami sebagai atribut. Artinya, kita dapat mengakses setiap atribut ini dengan pencarian menggunakan metode titik. Di sini, kita dapat mencetak Indeks row_namedtuple terakhir menggunakan row_namedtuple. Indeks. Kita dapat mencetak Tim row_namedtuple ini dengan row_namedtuple. Tim, Tahun dengan row_namedtuple. Tahun dan seterusnya
Ketika kita membandingkan. iterrows to. itertuples, kami melihat ada sedikit peningkatan
Alasannya. itertuples lebih efisien daripada. iterrows disebabkan oleh cara setiap metode menyimpan keluarannya. Sejak. iterrows mengembalikan nilai setiap baris sebagai Seri panda, ada sedikit lebih banyak overhead
2. 2. Alternatif Panda untuk Looping
Untuk menulis kode yang efisien, kami ingin menghindari perulangan sebanyak mungkin. Oleh karena itu sekarang kita akan mengeksplorasi alternatif untuk menggunakan. iterrows dan. itertuples untuk melakukan perhitungan pada DataFrame
Kami akan terus menggunakan kumpulan data bisbol. Pertama-tama kita akan membuat fungsi calc_run_diff. Fungsi ini menghitung perbedaan lari tim untuk tahun tertentu dengan mengurangkan jumlah total lari yang diperbolehkan tim dari jumlah total lari yang dicetak dalam satu musim
Kami ingin membuat kolom baru di Baseball_df DataFrame kami yang disebut RD yang menyimpan perbedaan lari setiap tim selama bertahun-tahun. Sebelumnya kami melakukan ini dengan for loop menggunakan keduanya. iterrows atau. itertuples. Di sini, kita akan menggunakan. iterrows sebagai contoh. Perhatikan bahwa kita mengulangi baseball_df dengan loop for, meneruskan kolom RS dan RA setiap baris ke fungsi calc_run_diff kita, lalu menambahkan hasil setiap baris ke daftar run_diffs_iterrows kita. Ini memberi kami hasil yang kami inginkan, tetapi itu bukan pilihan kami yang paling efisien
Panda. berlaku() Metode
Salah satu alternatif untuk menggunakan loop untuk mengulang DataFrame adalah dengan menggunakan panda. menerapkan metode. Fungsi ini bertindak seperti fungsi peta. Dibutuhkan fungsi sebagai input dan menerapkan fungsi ini ke seluruh DataFrame. Karena kami bekerja dengan data tabular, kami harus menentukan sumbu yang kami ingin fungsi kami lakukan. Menggunakan nol untuk argumen sumbu akan menerapkan fungsi kita pada kolom sementara menggunakan satu untuk sumbu akan menerapkan fungsi kita pada semua baris. Sama seperti fungsi peta, panda. menerapkan metode dapat digunakan dengan fungsi anonim atau lambda
Mari kita telusuri bagaimana kita akan menggunakan. menerapkan metode untuk menghitung diferensial run kami. Pertama, kami menelepon. terapkan pada Baseball_df DataFrame. Kemudian, kami menggunakan fungsi lambda untuk mengulangi baris DataFrame. Perhatikan bahwa argumen kami untuk lambda adalah baris (karena kami menerapkan ke setiap baris DataFrame). Untuk setiap baris, kami mengambil kolom RS dan RA dan meneruskannya ke fungsi calc_run_diff kami. Terakhir, kami menentukan sumbu kami untuk memberi tahu dot-apply bahwa kami ingin mengulangi baris, bukan kolom
Ketika kita menggunakan. terapkan metode untuk menghitung diferensial run kami, kami tidak perlu menggunakan for a loop. Kami dapat mengumpulkan diferensial run kami langsung ke objek yang disebut run_diffs_apply
Kita dapat melihat bahwa. pendekatan iterrows membutuhkan waktu sekitar 321 milidetik untuk menyelesaikannya. Tapi, menggunakan metode dot-apply hanya butuh 45. 2 milidetik. Peningkatan yang pasti
2. 3. Iterasi Panda yang Optimal
Kami telah menempuh perjalanan jauh dari yang pertama. pendekatan iloc untuk iterasi melalui DataFrame. Setiap pendekatan yang telah kita diskusikan benar-benar meningkatkan kinerja. Namun, pendekatan ini berfokus pada melakukan penghitungan untuk setiap baris DataFrame kami satu per satu. Sekarang kita akan menjelajahi beberapa internal panda yang memungkinkan kita melakukan perhitungan dengan lebih efisien
Karena panda adalah perpustakaan yang dibangun di atas NumPy. Ini berarti bahwa setiap DataFrame panda yang kita gunakan dapat memanfaatkan karakteristik efisien dari array NumPy yang dibahas di artikel sebelumnya. Kami membahas penyiaran dan bagaimana hal itu memungkinkan array NumPy untuk memvektorisasi operasi, sehingga dilakukan pada semua elemen objek sekaligus. Ini memungkinkan kami untuk melakukan perhitungan secara efisien di seluruh array. Sama seperti NumPy, panda dirancang untuk membuat perhitungan menjadi vektor sehingga mereka beroperasi pada seluruh kumpulan data sekaligus (tidak hanya berdasarkan baris demi baris). Mari jelajahi konsep ini dengan beberapa contoh
Kami akan terus menggunakan Baseball_df DataFrame yang telah kami gunakan di sepanjang bab ini. Karena panda dibangun di atas NumPy, kita dapat mengambil salah satu dari nilai kolom DataFrame ini sebagai larik NumPy menggunakan metode dot-values. Di sini, kami mengumpulkan nilai kolom W ke dalam larik NumPy bernama wins_np. Saat kami mencetak tipe wins_np, kami melihat bahwa itu sebenarnya adalah array NumPy
Kita dapat melihat isi array dengan mencetaknya dan memverifikasi bahwa itu sama dengan kolom W dari DataFrame kita
Keindahan mengetahui bahwa panda dibangun di atas NumPy dapat dilihat saat memanfaatkan kemampuan penyiaran array NumPy. Ingat, ini berarti kita dapat membuat vektor kalkulasi kita, dan menjalankannya pada seluruh array sekaligus. Alih-alih mengulang DataFrame, dan memperlakukan setiap baris secara independen, seperti yang telah kita lakukan. iterrows,. itertuples, dan. berlaku, kita dapat melakukan perhitungan pada array NumPy yang mendasari DataFrame baseball_df kita. Di sini, kami mengumpulkan kolom RS dan RA di DataFrame kami sebagai larik NumPy, dan menggunakan penyiaran untuk menghitung perbedaan lari sekaligus
Saat kami menggunakan larik NumPy untuk menjalankan kalkulasi diferensial yang dijalankan, kami dapat melihat bahwa kode kami menjadi jauh lebih mudah dibaca. Di sini, kita dapat secara eksplisit melihat bagaimana perbedaan proses kita dihitung. Juga ketika kami mengatur waktu pendekatan array NumPy kami, kami melihat bahwa perhitungan diferensial berjalan kami membutuhkan waktu mikrodetik. Semua pendekatan lain dilaporkan dalam milidetik. Pendekatan array kami jauh lebih cepat daripada semua pendekatan sebelumnya. Jelas bahwa menggunakan array NumPy yang mendasari DataFrame untuk melakukan perhitungan dapat membantu kami mendapatkan beberapa efisiensi besar-besaran
3. Referensi
- Menulis Kode Python yang Efisien
- Kode dan kumpulan data dapat ditemukan di repositori GitHub ini
GitHub - youssefHosni/Advanced-Python-Programming-Tutorials-
Anda tidak dapat melakukan tindakan tersebut saat ini. Anda masuk dengan tab atau jendela lain. Anda keluar di tab lain atau…
github. com
Bergabunglah dengan Medium dengan tautan referensi saya - Youssef Hosni
Baca setiap cerita dari Youssef Hosni (dan ribuan penulis lain di Medium). Biaya keanggotaan Anda secara langsung mendukung…
youssefraafat57. medium. com
Terima kasih sudah membaca. Jika Anda menyukai artikelnya, pastikan untuk bertepuk tangan (hingga 50. ) dan terhubung dengan saya di LinkedIn dan ikuti saya di Medium untuk terus mengikuti artikel baru saya