Saya telah mencoba mencari jawaban untuk pertanyaan ini selama berbulan-bulan sambil belajar panda. Saya menggunakan SAS untuk pekerjaan saya sehari-hari dan itu sangat bagus untuk itu dukungan di luar inti. Namun, SAS mengerikan sebagai bagian dari perangkat lunak karena berbagai alasan lainnya.
Suatu hari saya berharap untuk mengganti penggunaan SAS saya dengan python dan panda, tapi saat ini saya kekurangan alur kerja out-of-core untuk dataset besar. Saya tidak berbicara tentang "data besar" yang memerlukan jaringan terdistribusi, melainkan file yang terlalu besar untuk muat di memori tetapi cukup kecil untuk muat di hard-drive.
Pikiran pertama saya adalah menggunakan HDFStore
untuk menyimpan dataset besar pada disk dan hanya menarik bagian yang saya butuhkan ke dalam kerangka data untuk dianalisis. Yang lain menyebutkan MongoDB sebagai alternatif yang lebih mudah digunakan. Pertanyaan saya adalah ini:
Apa saja alur kerja praktik terbaik untuk mencapai yang berikut ini:
- Memuat file rata ke dalam struktur basis data disk permanen
- Meminta basis data itu untuk mengambil data untuk dimasukkan ke dalam struktur data panda
- Memperbarui database setelah memanipulasi potongan dalam panda
Contoh dunia nyata akan sangat dihargai, terutama dari siapa pun yang menggunakan panda pada "data besar".
Edit - contoh bagaimana saya ingin ini berfungsi:
- Mengimpor file flat besar secara besar-besaran dan menyimpannya dalam struktur basis data on-disk yang permanen. File-file ini biasanya terlalu besar untuk muat di memori.
- Untuk menggunakan Panda, saya ingin membaca himpunan bagian dari data ini (biasanya hanya beberapa kolom pada satu waktu) yang dapat ditampung dalam memori.
- Saya akan membuat kolom baru dengan melakukan berbagai operasi pada kolom yang dipilih.
- Saya kemudian harus menambahkan kolom baru ini ke dalam struktur basis data.
Saya mencoba menemukan cara praktik terbaik untuk melakukan langkah-langkah ini. Membaca tautan tentang panda dan pytables tampaknya menambahkan kolom baru bisa menjadi masalah.
Sunting - Menanggapi pertanyaan Jeff secara khusus:
- Saya sedang membangun model risiko kredit konsumen. Jenis data termasuk telepon, SSN dan karakteristik alamat; nilai properti; informasi yang merendahkan seperti catatan kriminal, kebangkrutan, dll ... Kumpulan data yang saya gunakan setiap hari rata-rata memiliki hampir 1.000 hingga 2.000 bidang data campuran: variabel kontinu, nominal dan ordinal dari data numerik dan karakter. Saya jarang menambahkan baris, tetapi saya melakukan banyak operasi yang membuat kolom baru.
- Operasi tipikal melibatkan menggabungkan beberapa kolom menggunakan logika kondisional ke dalam kolom gabungan yang baru. Sebagai contoh
if var1 > 2 then newvar = 'A' elif var2 = 4 then newvar = 'B'
,. Hasil dari operasi ini adalah kolom baru untuk setiap catatan dalam dataset saya. - Akhirnya, saya ingin menambahkan kolom baru ini ke dalam struktur data pada disk. Saya akan mengulangi langkah 2, mengeksplorasi data dengan tab silang dan statistik deskriptif yang berusaha menemukan hubungan yang menarik, intuitif dengan model.
- File proyek tipikal biasanya sekitar 1GB. File disusun sedemikian rupa di mana baris terdiri dari catatan data konsumen. Setiap baris memiliki jumlah kolom yang sama untuk setiap catatan. Ini akan selalu menjadi masalah.
- Sangat jarang bahwa saya akan subset oleh baris ketika membuat kolom baru. Namun, sangat umum bagi saya untuk membuat subset pada baris ketika membuat laporan atau menghasilkan statistik deskriptif. Misalnya, saya mungkin ingin membuat frekuensi sederhana untuk lini bisnis tertentu, misalnya kartu kredit Ritel. Untuk melakukan ini, saya hanya akan memilih catatan-catatan di mana garis bisnis = ritel di samping kolom mana pun yang ingin saya laporkan. Ketika membuat kolom baru, saya akan menarik semua baris data dan hanya kolom yang saya butuhkan untuk operasi.
- Proses pemodelan mengharuskan saya menganalisis setiap kolom, mencari hubungan yang menarik dengan beberapa variabel hasil, dan membuat kolom gabungan baru yang menggambarkan hubungan tersebut. Kolom yang saya jelajahi biasanya dilakukan dalam set kecil. Sebagai contoh, saya akan fokus pada satu set katakan 20 kolom hanya berurusan dengan nilai properti dan amati bagaimana mereka berhubungan dengan default pada pinjaman. Setelah itu dieksplorasi dan kolom baru dibuat, saya kemudian pindah ke grup kolom lain, katakanlah pendidikan perguruan tinggi, dan ulangi prosesnya. Apa yang saya lakukan adalah membuat variabel kandidat yang menjelaskan hubungan antara data saya dan beberapa hasil. Di akhir proses ini, saya menerapkan beberapa teknik pembelajaran yang membuat persamaan dari kolom-kolom majemuk tersebut.
Jarang sekali saya menambahkan baris ke dataset. Saya hampir selalu akan membuat kolom baru (variabel atau fitur dalam statistik / bahasa pembelajaran mesin).
Jawaban:
Saya secara rutin menggunakan puluhan gigabyte data hanya dengan cara ini misalnya saya punya tabel pada disk yang saya baca melalui query, membuat data dan menambahkan kembali.
Ada baiknya membaca dokumen dan terlambat di utas ini untuk beberapa saran tentang cara menyimpan data Anda.
Detail yang akan memengaruhi cara Anda menyimpan data, seperti:
Berikan detail sebanyak mungkin; dan saya dapat membantu Anda mengembangkan struktur.
(Memberikan contoh mainan dapat memungkinkan kami untuk menawarkan rekomendasi yang lebih spesifik.)
Larutan
Pastikan Anda memiliki panda setidaknya
0.10.1
diinstal.Baca iterasi file chunk-by-chunk dan beberapa tabel query .
Karena pytables dioptimalkan untuk beroperasi pada baris-bijaksana (yang merupakan permintaan Anda), kami akan membuat tabel untuk setiap kelompok bidang. Dengan cara ini mudah untuk memilih sekelompok kecil bidang (yang akan bekerja dengan tabel besar, tetapi lebih efisien untuk melakukannya dengan cara ini ... Saya pikir saya mungkin dapat memperbaiki batasan ini di masa depan ... ini adalah lebih intuitif bagaimanapun):
(Berikut ini adalah kodesemu.)
Membaca dalam file dan membuat penyimpanan (pada dasarnya melakukan apa yang
append_to_multiple
dilakukan):Sekarang Anda memiliki semua tabel dalam file (sebenarnya Anda bisa menyimpannya dalam file terpisah jika Anda mau, Anda mungkin harus menambahkan nama file ke group_map, tetapi mungkin ini tidak perlu).
Ini adalah cara Anda mendapatkan kolom dan membuat yang baru:
Ketika Anda siap untuk post_processing:
Tentang data_columns, Anda sebenarnya tidak perlu mendefinisikan ANY data_columns; mereka memungkinkan Anda untuk memilih sub-baris berdasarkan pada kolom. Misalnya sesuatu seperti:
Mereka mungkin paling menarik bagi Anda dalam tahap pembuatan laporan akhir (pada dasarnya kolom data dipisahkan dari kolom lain, yang mungkin agak berdampak pada efisiensi jika Anda mendefinisikan banyak).
Anda juga mungkin ingin:
Beri tahu saya jika Anda memiliki pertanyaan!
sumber
Saya pikir jawaban di atas tidak memiliki pendekatan sederhana yang menurut saya sangat berguna.
Ketika saya memiliki file yang terlalu besar untuk dimuat dalam memori, saya memecah file menjadi beberapa file yang lebih kecil (baik dengan baris atau cols)
Contoh: Dalam hal data perdagangan senilai 30 hari ukuran ~ 30GB, saya memecahnya menjadi file per hari ukuran ~ 1GB. Saya kemudian memproses setiap file secara terpisah dan mengumpulkan hasilnya pada akhirnya
Salah satu keuntungan terbesar adalah memungkinkan pemrosesan paralel file (baik beberapa utas atau proses)
Keuntungan lainnya adalah manipulasi file (seperti menambah / menghapus tanggal pada contoh) dapat dilakukan dengan perintah shell biasa, yang tidak mungkin dilakukan dalam format file yang lebih maju / rumit
Pendekatan ini tidak mencakup semua skenario, tetapi sangat berguna dalam banyak skenario
sumber
Sekarang ada, dua tahun setelah pertanyaan, sebuah panda 'out-of-core' setara: dask . Itu sangat baik! Meskipun tidak mendukung semua fungsionalitas panda, Anda dapat melakukannya dengan sangat baik.
sumber
dask
.Jika kumpulan data Anda antara 1 dan 20GB, Anda harus mendapatkan workstation dengan 48GB RAM. Kemudian Pandas dapat menyimpan seluruh dataset dalam RAM. Saya tahu ini bukan jawaban yang Anda cari di sini, tetapi melakukan komputasi ilmiah pada notebook dengan 4GB RAM tidak masuk akal.
sumber
Saya tahu ini adalah utas lama tapi saya pikir perpustakaan Blaze layak untuk dicoba. Itu dibangun untuk situasi semacam ini.
Dari dokumen:
Blaze memperluas kegunaan NumPy dan Panda untuk komputasi terdistribusi dan out-of-core. Blaze menyediakan antarmuka yang mirip dengan NumPy ND-Array atau Pandas DataFrame tetapi memetakan antarmuka yang sudah dikenal ini ke berbagai mesin komputasi lain seperti Postgres atau Spark.
Sunting: Omong-omong, didukung oleh ContinuumIO dan Travis Oliphant, penulis NumPy.
sumber
Ini adalah kasus untuk pymongo. Saya juga telah membuat prototipe menggunakan sql server, sqlite, HDF, ORM (SQLAlchemy) dalam python. Pymongo pertama dan terpenting adalah DB berbasis dokumen, sehingga setiap orang akan menjadi dokumen (
dict
atribut). Banyak orang membentuk koleksi dan Anda dapat memiliki banyak koleksi (orang, pasar saham, pendapatan).pd.dateframe -> pymongo Catatan: Saya menggunakan
chunksize
dalamread_csv
untuk menyimpannya hingga 5 hingga 10 ribu catatan (pymongo menjatuhkan soket jika lebih besar)kueri: gt = lebih besar dari ...
.find()
mengembalikan sebuah iterator jadi saya biasanya gunakanichunked
untuk memotong iterator yang lebih kecil.Bagaimana dengan bergabung karena saya biasanya mendapatkan 10 sumber data untuk disatukan:
lalu (dalam kasus saya kadang-kadang saya harus melakukan ag
aJoinDF
terlebih dahulu sebelum "dapat digabungkan".)Dan Anda kemudian dapat menulis info baru ke koleksi utama Anda melalui metode pembaruan di bawah ini. (pengumpulan logis vs sumber data fisik).
Pada pencarian yang lebih kecil, cukup denormalkan. Misalnya, Anda memiliki kode dalam dokumen dan Anda hanya menambahkan teks kode bidang dan melakukan
dict
pencarian saat Anda membuat dokumen.Sekarang Anda memiliki dataset yang bagus berdasarkan pada seseorang, Anda dapat melepaskan logika Anda pada setiap kasus dan membuat lebih banyak atribut. Akhirnya, Anda dapat membaca panda indikator kunci maksimal 3 ke memori dan melakukan eksplorasi pivot / ag / data. Ini bekerja untuk saya selama 3 juta catatan dengan angka / teks besar / kategori / kode / mengapung / ...
Anda juga dapat menggunakan dua metode yang dibangun ke dalam MongoDB (kerangka MapReduce dan agregat). Lihat di sini untuk info lebih lanjut tentang kerangka kerja agregat , karena tampaknya lebih mudah daripada MapReduce dan terlihat berguna untuk pekerjaan agregat cepat. Perhatikan saya tidak perlu mendefinisikan bidang atau relasi saya, dan saya bisa menambahkan item ke dokumen. Pada keadaan saat ini dari numpy, panda, python toolset yang berubah dengan cepat, MongoDB membantu saya untuk mulai bekerja :)
sumber
In [96]: test.insert((a[1].to_dict() for a in df.iterrows())) --------------- InvalidDocument: Cannot encode object: 0
. Ada ide apa yang mungkin salah? Dataframe saya terdiri dari semua int64 dtypes dan sangat sederhana.Saya melihat ini agak terlambat, tetapi saya bekerja dengan masalah yang sama (model pembayaran di muka hipotek). Solusi saya adalah dengan melewatkan layer HDFStore panda dan menggunakan pytables lurus. Saya menyimpan setiap kolom sebagai array HDF5 individu di file terakhir saya.
Alur kerja dasar saya adalah pertama-tama mendapatkan file CSV dari database. Saya gzip, jadi tidak sebesar ini. Kemudian saya mengonversinya menjadi file HDF5 berorientasi baris, dengan mengulanginya menggunakan python, mengubah setiap baris menjadi tipe data nyata, dan menulisnya ke file HDF5. Itu membutuhkan waktu puluhan menit, tetapi tidak menggunakan memori apa pun, karena hanya beroperasi baris demi baris. Lalu saya "memindahkan" file HDF5 yang berorientasi baris menjadi file HDF5 yang berorientasi kolom.
Tabel transpos terlihat seperti:
Membaca kembali kemudian terlihat seperti:
Sekarang, saya biasanya menjalankan ini pada mesin dengan banyak memori, jadi saya mungkin tidak cukup berhati-hati dengan penggunaan memori saya. Misalnya, secara default operasi pemuatan membaca seluruh kumpulan data.
Ini umumnya bekerja untuk saya, tapi agak kikuk, dan saya tidak bisa menggunakan sihir pytables yang mewah.
Sunting: Keuntungan nyata dari pendekatan ini, daripada array-of-records pytables default, adalah bahwa saya kemudian dapat memuat data ke R menggunakan h5r, yang tidak dapat menangani tabel. Atau, setidaknya, saya tidak dapat membuatnya memuat tabel heterogen.
sumber
Salah satu trik yang saya temukan bermanfaat untuk kasus penggunaan data yang besar adalah mengurangi volume data dengan mengurangi presisi float menjadi 32-bit. Ini tidak berlaku dalam semua kasus, tetapi dalam banyak aplikasi presisi 64-bit berlebihan dan penghematan memori 2x sepadan. Untuk membuat poin yang jelas semakin jelas:
sumber
Sebagaimana dicatat oleh orang lain, setelah beberapa tahun, panda setara 'out-of-core' telah muncul: dask . Meskipun dask bukanlah pengganti panda yang drop-in dan semua fungsinya, ia menonjol karena beberapa alasan:
Dask adalah perpustakaan komputasi paralel fleksibel untuk komputasi analitik yang dioptimalkan untuk penjadwalan tugas dinamis untuk beban kerja komputasi interaktif dari koleksi "Big Data" seperti array paralel, kerangka data, dan daftar yang memperluas antarmuka umum seperti NumPy, Pandas, atau iterator Python ke yang lebih besar- dari-memori atau lingkungan terdistribusi dan skala dari laptop ke cluster.
dan untuk menambahkan contoh kode sederhana:
mengganti beberapa kode panda seperti ini:
dan, terutama yang patut diperhatikan, menyediakan
concurrent.futures
antarmuka umum infrastruktur untuk pengiriman tugas kustom melalui antarmuka:sumber
Layak disebutkan di sini Ray juga,
ini adalah kerangka perhitungan terdistribusi, yang memiliki implementasi sendiri untuk panda dengan cara terdistribusi.
Cukup ganti impor panda, dan kodenya harus berfungsi apa adanya:
dapat membaca lebih detail di sini:
https://rise.cs.berkeley.edu/blog/pandas-on-ray/
sumber
Satu lagi variasi
Banyak operasi yang dilakukan dalam panda juga dapat dilakukan sebagai permintaan db (sql, mongo)
Menggunakan RDBMS atau mongodb memungkinkan Anda untuk melakukan beberapa agregasi di DB Query (yang dioptimalkan untuk data besar, dan menggunakan cache dan indeks secara efisien)
Kemudian, Anda dapat melakukan pemrosesan pos menggunakan panda.
Keuntungan dari metode ini adalah Anda mendapatkan optimisasi DB untuk bekerja dengan data besar, sambil tetap mendefinisikan logika dalam sintaks deklaratif tingkat tinggi - dan tidak harus berurusan dengan detail memutuskan apa yang harus dilakukan dalam memori dan apa yang harus dilakukan inti.
Dan meskipun bahasa query dan panda berbeda, biasanya tidak rumit untuk menerjemahkan bagian dari logika dari satu ke yang lain.
sumber
Pertimbangkan Ruffus jika Anda menggunakan jalur sederhana untuk membuat pipa data yang dipecah menjadi beberapa file yang lebih kecil.
sumber
Baru-baru ini saya menemukan masalah yang sama. Saya menemukan hanya membaca data dalam potongan dan menambahkannya saat saya menulis dalam potongan untuk csv yang sama berfungsi dengan baik. Masalah saya adalah menambahkan kolom tanggal berdasarkan informasi di tabel lain, menggunakan nilai kolom tertentu sebagai berikut. Ini dapat membantu mereka yang bingung oleh dask dan hdf5 tetapi lebih terbiasa dengan panda seperti saya.
sumber
Saya ingin menunjukkan paket Vaex.
Lihat dokumentasi: https://vaex.readthedocs.io/en/latest/ API sangat dekat dengan API panda.
sumber
Mengapa panda? Sudahkah Anda mencoba Standard Python ?
Penggunaan python perpustakaan standar. Panda tunduk pada pembaruan yang sering, bahkan dengan rilis terbaru dari versi stabil.
Menggunakan pustaka python standar kode Anda akan selalu berjalan.
Salah satu cara melakukannya adalah memiliki gagasan tentang cara Anda ingin data Anda disimpan, dan pertanyaan mana yang ingin Anda selesaikan terkait data tersebut. Kemudian gambarkan skema bagaimana Anda bisa mengatur data Anda (think tables) yang akan membantu Anda meminta data, tidak harus normalisasi.
Anda dapat memanfaatkan:
Ram dan HDD menjadi lebih murah dan lebih murah dengan waktu dan standar python 3 tersedia secara luas dan stabil.
sumber
Saat ini saya bekerja "seperti" Anda, hanya pada skala yang lebih rendah, itulah sebabnya saya tidak memiliki PoC untuk saran saya.
Namun, saya sepertinya menemukan sukses dalam menggunakan acar sebagai sistem caching dan outsourcing pelaksanaan berbagai fungsi ke dalam file - mengeksekusi file-file ini dari commando / file utama saya; Misalnya saya menggunakan prep_use.py untuk mengkonversi tipe objek, membagi set data menjadi tes, memvalidasi dan set data prediksi.
Bagaimana cara caching Anda dengan acar bekerja? Saya menggunakan string untuk mengakses file acar yang dibuat secara dinamis, tergantung pada parameter dan kumpulan data yang dilewati (dengan itu saya mencoba untuk menangkap dan menentukan apakah program sudah dijalankan, menggunakan .shape untuk set data, dict untuk disahkan parameter). Menghormati langkah-langkah ini, saya mendapatkan sebuah String untuk mencoba menemukan dan membaca file .pickle dan dapat, jika ditemukan, melewatkan waktu pemrosesan untuk melompat ke eksekusi yang sedang saya kerjakan sekarang.
Menggunakan database saya mengalami masalah yang sama, itulah sebabnya saya menemukan sukacita dalam menggunakan solusi ini, namun - ada banyak kendala pasti - misalnya menyimpan set acar besar karena redundansi. Memperbarui tabel dari sebelum ke setelah transformasi dapat dilakukan dengan pengindeksan yang tepat - memvalidasi informasi membuka seluruh buku lain (saya mencoba mengkonsolidasikan data sewaan merangkak dan berhenti menggunakan database setelah 2 jam pada dasarnya - karena saya ingin melompat kembali setelah setiap proses transformasi)
Saya harap 2 sen saya membantu Anda dalam beberapa cara.
Salam pembuka.
sumber