Mengapa panda digabung dalam python lebih cepat dari data.tabel digabung dalam R pada 2012?

160

Saya baru-baru ini menemukan panda library untuk python, yang menurut tolok ukur ini melakukan penggabungan in-memory yang sangat cepat. Ini bahkan lebih cepat daripada paket data.table di R (bahasa pilihan saya untuk analisis).

Mengapa pandasjauh lebih cepat daripada data.table? Apakah karena keuntungan kecepatan python yang melekat memiliki lebih dari R, atau apakah ada tradeoff yang saya tidak sadari? Apakah ada cara untuk melakukan gabungan dalam dan luar data.tabletanpa menggunakan merge(X, Y, all=FALSE)dan merge(X, Y, all=TRUE)?

Perbandingan

Berikut kode R dan kode Python yang digunakan untuk membandingkan berbagai paket.

Zach
sumber
10
@JoshuaUlrich: IIRC data.tablehanya mewarisi dari data.frame, tetapi bergantung pada kode-C di bawah tenda.
digEmAll
4
@ Joshua Apa yang Anda maksud dengan "data.frame lambat bahkan jika Anda memanipulasinya dalam C"? Apakah itu relatif terhadap sesuatu yang lain? Dan lambat pada apa?
Matt Dowle
12
@ JoshuaUlrich Saya baru saja memperhatikan jejak komentar ini tidak pernah diletakkan di tempat tidur. Jadi untuk menjernihkannya: set()ditambahkan data.tablesegera setelah diskusi ini. Sangat mirip dengan :=tetapi menghindari overhead kecil [.data.tableketika dilingkarkan dan akibatnya secepat matrix. Oleh karena itu, data.frame dapat dimanipulasi secepat matriks. Benchmark ada di sini .
Matt Dowle
5
Bisakah kita mendapatkan versi terbaru dari tolok ukur ini, cukup jelas bahwa bangku ini sebenarnya adalah casing tepi dan ini sudah diperbaiki sekarang. Mengingat bahwa semua tolok ukur yang saya lihat menunjukkan bahwa data.tabel lebih cepat Saya ingin melihat apa nomor gabungan?
statquant
3
@statquant Saya tidak menjalankan benchmark asli, tapi saya benar-benar ingin melihat Wes memperbarui benchmark.
Zach

Jawaban:

120

Sepertinya Wes mungkin telah menemukan masalah yang diketahui data.tableketika jumlah string unik ( level ) besar: 10.000.

Apakah Rprof()mengungkapkan sebagian besar waktu yang dihabiskan dalam panggilan sortedmatch(levels(i[[lc]]), levels(x[[rc]])? Ini bukan benar-benar bergabung sendiri (algoritma), tetapi merupakan langkah awal.

Upaya terbaru telah dilakukan untuk memungkinkan kolom karakter dalam kunci, yang harus menyelesaikan masalah itu dengan mengintegrasikan lebih dekat dengan tabel hash string global R itu sendiri. Beberapa hasil benchmark sudah dilaporkan oleh test.data.table()tetapi kode itu belum terhubung untuk mengganti level ke level yang cocok.

Apakah panda digabung lebih cepat daripada data.tablekolom bilangan bulat biasa? Itu harus menjadi cara untuk mengisolasi algoritma itu sendiri vs masalah faktor.

Juga, data.tablememiliki deret waktu bergabung dalam pikiran. Dua aspek itu: i) multi-kolom memerintahkan kunci seperti (id, datetime) ii) berlaku cepat bergabung ( roll=TRUE) pengamatan terakhir alias dilakukan ke depan.

Saya perlu waktu untuk mengonfirmasi karena ini adalah perbandingan pertama yang saya data.tablesajikan.


PEMBARUAN dari data.tabel v1.8.0 dirilis Juli 2012

  • Fungsi internal sortmatch () dihapus dan diganti dengan chmatch () saat mencocokkan level i ke level x untuk kolom tipe 'faktor'. Langkah awal ini menyebabkan perlambatan signifikan (diketahui) ketika jumlah level kolom faktor besar (mis.> 10.000). Diperburuk dalam tes bergabung dengan empat kolom seperti itu, seperti yang ditunjukkan oleh Wes McKinney (penulis paket Python Pandora). Mencocokkan 1 juta string yang 600.000 di antaranya unik sekarang dikurangi dari 16 menjadi 0,5, misalnya.

juga dalam rilis itu adalah:

  • kolom karakter sekarang diizinkan di tombol dan lebih disukai untuk faktor. data.table () dan setkey () tidak lagi memaksa karakter untuk faktor. Faktor masih didukung. Menerapkan FR # 1493, FR # 1224 dan (sebagian) FR # 951.

  • Fungsi baru chmatch () dan% chin%, versi kecocokan yang lebih cepat () dan% in% untuk vektor karakter. Cache string internal R digunakan (tidak ada tabel hash dibangun). Mereka sekitar 4 kali lebih cepat daripada pertandingan () pada contoh di? Chmatch.

Pada Sep 2013 data.table adalah v1.8.10 tentang CRAN dan kami sedang mengerjakan v1.9.0. BERITA diperbarui langsung.


Tapi seperti yang saya tulis awalnya, di atas:

data.tablememiliki penggabungan deret waktu . Dua aspek itu: i) multi-kolom memerintahkan kunci seperti (id, datetime) ii) berlaku cepat bergabung ( roll=TRUE) pengamatan terakhir alias dilakukan ke depan.

Jadi gabungan Pandas dari dua kolom karakter mungkin masih lebih cepat daripada data.table. Karena kedengarannya seperti hash gabungan dua kolom. data.table tidak memiliki kunci karena telah berlaku memerintahkan bergabung dalam pikiran. "Kunci" dalam data.table secara harfiah hanya urutan (mirip dengan indeks berkerumun di SQL; yaitu, itulah cara data dipesan dalam RAM). Di daftar adalah menambahkan kunci sekunder, misalnya.

Singkatnya, perbedaan kecepatan mencolok yang disorot oleh uji dua karakter kolom khusus ini dengan lebih dari 10.000 string unik seharusnya tidak seburuk sekarang, karena masalah yang diketahui telah diperbaiki.

Matt Dowle
sumber
6
Jika Anda memberikan test case untuk set data realistis yang cukup besar, saya akan dengan senang hati menjalankan benchmark. Anda dipersilakan juga. Saya sebenarnya belum mengoptimalkan kode untuk kasus kunci integer join (letakkan di daftar todo saya!), Tetapi Anda dapat mengharapkan kinerja yang jauh lebih baik daripada case string yang diberikan studi tabel hash dalam presentasi yang ditautkan.
Wes McKinney
22
Saya tidak menggunakan salah satu dari perpustakaan ini tetapi senang melihat respon konstruktif dari sisi R dalam bentuk Matthew Dowle.
SlowLearner
3
Inilah beberapa hasil Rprof pastie.org/3258362 . Sepertinya 20-40% dari waktu dihabiskan di sortmatch tergantung pada tipe join. Harus melihat kolom integer di lain waktu - Saya membuat masalah panda GitHub untuk mengingatkan saya untuk mengoptimalkan kasing itu ( github.com/wesm/pandas/issues/682 )
Wes McKinney
14
@AndyHayden Perbaikan dilakukan beberapa waktu lalu. Saya akan mengedit item NEWS. Wes memilih satu tes khusus (equi bergabung dengan dua kolom karakter) yang dimainkan pada masalah yang diketahui. Jika dia memilih kolom bilangan bulat itu akan berbeda. Dan jika dia memberi saya kepala sebelum mempresentasikan benchmark di konferensi maka saya bisa memberi tahu dia lebih banyak tentang masalah yang diketahui.
Matt Dowle
191

Alasan panda lebih cepat adalah karena saya datang dengan algoritma yang lebih baik, yang diimplementasikan dengan sangat hati-hati menggunakan implementasi tabel hash cepat - klib dan di C / Cython untuk menghindari overhead juru bahasa Python untuk bagian-bagian yang tidak dapat di-vektorisasi. Algoritma ini dijelaskan secara terperinci dalam presentasi saya: Pandangan di dalam desain dan pengembangan panda .

Perbandingan dengan data.tableini sebenarnya sedikit menarik karena seluruh poin R data.tableadalah mengandung indeks pra-komputasi untuk berbagai kolom untuk mempercepat operasi seperti pemilihan dan penggabungan data. Dalam kasus ini (basis data bergabung) DataFrame panda tidak mengandung informasi pra-komputasi yang digunakan untuk penggabungan, sehingga untuk berbicara itu adalah penggabungan "dingin". Jika saya telah menyimpan versi faktorisasi dari kunci bergabung, bergabung akan jauh lebih cepat - karena faktorisasi adalah hambatan terbesar untuk algoritma ini.

Saya juga harus menambahkan bahwa desain internal DataFrame panda jauh lebih cocok untuk jenis operasi ini daripada data.frame R (yang hanya daftar array secara internal).

Wes McKinney
sumber
76
Tentu saja, sekarang setelah Anda mengetahuinya dengan python, seharusnya mudah diterjemahkan ke dalam R;)
hadley
37
Tapi mengapa ada orang yang mau? :)
ely
9
Umm ... mungkin karena mereka ingin operasi data menjadi lebih cepat di R? Hanya menebak :))
lebatsnok
28
Hai Wes-- tampaknya hasil Anda untuk data.tableutama didorong oleh bug yang telah diperbaiki. Apakah ada kemungkinan Anda dapat menjalankan kembali tolok ukur Anda dan menulis posting blog yang diperbarui?
Zach
6
Zach pastikan Anda memeriksanya: github.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping
Merik
37

Topik ini berumur dua tahun tetapi sepertinya tempat yang memungkinkan bagi orang untuk mendarat ketika mereka mencari perbandingan Pandas dan data.table

Karena keduanya telah berevolusi dari waktu ke waktu, saya ingin memposting perbandingan yang relatif lebih baru (dari 2014) di sini untuk pengguna yang tertarik: https://github.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping

Akan menarik untuk mengetahui apakah Wes dan / atau Matt (yang, bagaimanapun juga, adalah pencipta Pandas dan data. Tabel masing-masing dan keduanya berkomentar di atas) memiliki berita untuk ditambahkan di sini juga.

- PEMBARUAN -

Sebuah komentar yang diposting di bawah ini oleh jangorecki berisi tautan yang menurut saya sangat berguna: https://github.com/szilard/benchm-databases

https://github.com/szilard/benchm-databases/blob/master/plot.png

Grafik ini menggambarkan waktu rata-rata agregasi dan operasi gabungan untuk teknologi yang berbeda ( lebih rendah = lebih cepat ; perbandingan terakhir diperbarui pada bulan September 2016). Itu sangat mendidik bagi saya.

Kembali ke pertanyaan, R DT keydan R DTrujuk ke citarasa kunci / tidak dikunci dari data R. Tabel dan kebetulan lebih cepat dalam benchmark ini daripada Python Pyas ( Py pandas).

Merik
sumber
1
Saya baru saja memposting ini! Terima kasih telah menambahkan.
Zach
7
@Zach lihat ini: github.com/szilard/benchm-databases dan itu bagus juga: speakerdeck.com/szilard/…
jangorecki
1
@ Zach empat tahun kemudian hasil benchmark baru akhirnya muncul, lihat jawaban saya di bawah ini.
jangorecki
7

Ada jawaban yang bagus, terutama dibuat oleh penulis dari kedua alat yang ditanyakan. Jawaban Matt menjelaskan kasus yang dilaporkan dalam pertanyaan, bahwa itu disebabkan oleh bug, dan bukan gabungan algoritma. Bug diperbaiki pada hari berikutnya, lebih dari 7 tahun yang lalu sudah.

Dalam jawaban saya, saya akan memberikan beberapa waktu up-to-date operasi penggabungan untuk data.table dan panda. Perhatikan bahwa penggabungan plyr dan basis R tidak termasuk.

Pengaturan waktu yang saya sajikan berasal dari proyek db-benchmark , tolok ukur yang dapat terus-menerus dijalankan. Ini meningkatkan alat ke versi terbaru dan menjalankan kembali skrip patokan. Ini menjalankan banyak solusi perangkat lunak lainnya. Jika Anda tertarik dengan Spark, Dask dan beberapa lainnya pastikan untuk memeriksa tautannya.


Sampai sekarang ... (masih harus diimplementasikan: satu ukuran data lagi dan 5 pertanyaan lagi)

Kami menguji 2 ukuran data yang berbeda dari tabel LHS.
Untuk masing-masing ukuran data tersebut kami menjalankan 5 pertanyaan penggabungan berbeda.

Q1: LHS bergabung dalam RHS- kecil di bilangan bulat
q2: LHS bergabung dalam RHS-media di bilangan bulat
Q3: LHS luar bergabung RHS-media di bilangan bulat
Q4: LHS bergabung dalam RHS menengah atas faktor (kategoris)
Q5: LHS bergabung dalam RHS- besar pada integer

Meja RHS terdiri dari 3 ukuran berbeda

  • kecil diterjemahkan menjadi ukuran LHS / 1e6
  • media diterjemahkan ke ukuran LHS / 1e3
  • besar artinya ukuran LHS

Dalam semua kasus ada sekitar 90% baris yang cocok antara LHS dan RHS, dan tidak ada duplikat dalam kolom gabungan RHS (tidak ada produk kartesius).


Sampai sekarang (berjalan pada 2 November 2019)

panda 0.25.3 dirilis pada 1 November 2019
data.tabel 0.12.7 (92abb70) dirilis pada 2 November 2019

Pengaturan waktu di bawah ini dalam detik, untuk dua ukuran data LHS yang berbeda. Kolom pd2dtditambahkan rasio penyimpanan bidang berapa kali panda lebih lambat dari data.tabel.

  • Data LHS 0,5 GB
+-----------+--------------+----------+--------+
| question  |  data.table  |  pandas  |  pd2dt |
+-----------+--------------+----------+--------+
| q1        |        0.51  |    3.60  |      7 |
| q2        |        0.50  |    7.37  |     14 |
| q3        |        0.90  |    4.82  |      5 |
| q4        |        0.47  |    5.86  |     12 |
| q5        |        2.55  |   54.10  |     21 |
+-----------+--------------+----------+--------+
  • 5 GB data LHS
+-----------+--------------+----------+--------+
| question  |  data.table  |  pandas  |  pd2dt |
+-----------+--------------+----------+--------+
| q1        |        6.32  |    89.0  |     14 |
| q2        |        5.72  |   108.0  |     18 |
| q3        |       11.00  |    56.9  |      5 |
| q4        |        5.57  |    90.1  |     16 |
| q5        |       30.70  |   731.0  |     23 |
+-----------+--------------+----------+--------+
jangorecki
sumber
Terima kasih atas pembaruan dari masa depan! Bisakah Anda menambahkan kolom untuk implementasi R vs python data.table?
Zach
1
Saya pikir itu baik untuk hanya pergi ke situs web dan memeriksanya, bahkan untuk melihat R dt vs panda. Dan pyDT sebenarnya bukan bagian dari pertanyaan awal.
jangorecki