Cara mengoptimalkan loop dengan python

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

  1. 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
  2. Pengantar Optimasi Panda
    2. 1. Iterasi DataFrame Pandas
    2. 2. Alternatif Panda untuk Looping
    2. 3. Iterasi Panda yang Optimal
  3. 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

  1. Menulis Kode Python yang Efisien
  2. 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

Bagaimana Anda mengoptimalkan loop?

Teknik Pengoptimalan Putaran. .
Pengurangan Frekuensi (Gerakan Kode). Dalam pengurangan frekuensi, jumlah kode dalam loop berkurang. .
Putaran Membuka Gulungan. Loop unrolling adalah teknik transformasi loop yang membantu mengoptimalkan waktu eksekusi suatu program

Bagaimana efisiensi loop ditingkatkan?

Cara terbaik untuk meningkatkan kinerja loop adalah mengurangi jumlah pekerjaan yang dilakukan per iterasi dan mengurangi jumlah iterasi loop . Secara umum, beralih selalu lebih cepat daripada if-else , tetapi tidak selalu merupakan solusi terbaik.

Bagaimana cara mengoptimalkan kode Python untuk kecepatan?

Mari kita mulai. .
Algoritma & Struktur Data yang Tepat. Setiap struktur data memiliki pengaruh yang signifikan terhadap runtime. .
Menggunakan Fungsi dan Pustaka Bawaan. Fungsi bawaan Python adalah salah satu cara terbaik untuk mempercepat kode Anda. .
Gunakan Banyak Tugas. .
Lebih suka Pemahaman Daftar Daripada Loops. .
Impor yang Tepat. .
Penggabungan String

Bagaimana Anda mempercepat iterasi dengan Python?

Bagaimana Anda mempercepat iterasi Python?