Ketika memori kereta dan / atau dataset kecil dapat dengan aman dilemparkan ke dalam panda tanpa optimasi. Namun, jika datanya besar, muncul pertanyaan bagaimana memprosesnya atau paling tidak menghitungnya.
Diusulkan untuk melihat optimasi dalam miniatur agar tidak menarik dataset raksasa dari jaringan.
Sebagai dataset, kami akan menggunakan habrastatistics dengan komentar pengguna untuk 2019, yang tersedia untuk umum berkat satu pengguna yang bekerja keras:
datasetSebagai dasar informasi,
artikel yang diterjemahkan sebelumnya dari Habr akan digunakan, di mana banyak hal menarik tercampur.
Alih-alih bergabung
Set data habrastatistics dianggap kecil, meskipun menempati 288 MB dan terdiri dari 448.533 baris.
Tentu saja, Anda dapat menemukan lebih banyak data, tetapi agar tidak menggantung mobil, marilah kita memikirkannya.
Untuk kenyamanan operasi, kami akan menambahkan (cukup tulis baris pertama ke file) nama kolom:
a,b,c,d
Sekarang, jika Anda langsung memuat dataset ke panda dan memeriksa berapa banyak memori yang digunakannya
import os import time import pandas as pd import numpy as np gl = pd.read_csv('habr_2019_comments.csv',encoding='UTF') def mem_usage(pandas_obj): if isinstance(pandas_obj,pd.DataFrame): usage_b = pandas_obj.memory_usage(deep=True).sum() else:
lihat bahwa dia "makan" 436.1 MB:
RangeIndex: 448533 entries, 0 to 448532 Data columns (total 4 columns): a 448533 non-null object b 448533 non-null object c 448533 non-null object d 448528 non-null object dtypes: object(4) memory usage: 436.1 MB
Ini juga menunjukkan bahwa kita berurusan dengan kolom yang berisi data objek tipe.
Oleh karena itu, menurut
artikel , untuk kolom, perlu fokus pada optimasi yang dihitung untuk objek. Untuk semua kolom kecuali satu.
Kolom b berisi tanggal, dan, untuk kenyamanan perhitungan dan kejelasan lebih lanjut, lebih baik mengirimkannya ke indeks dataset. Untuk melakukan ini, ubah kode yang digunakan saat membaca dataset:
gl = pd.read_csv('habr_2019_comments.csv', parse_dates=['b'], encoding='UTF')
Sekarang tanggal dibaca sebagai indeks dataset dan konsumsi memori sedikit berkurang:
memory usage: 407.0 MB
Sekarang kami mengoptimalkan data dalam dataset itu sendiri di luar kolom dan indeks
Optimasi disebut: "Optimalisasi penyimpanan data jenis objek menggunakan variabel kategorikal".
Jika diterjemahkan ke dalam bahasa Rusia, maka kita perlu menggabungkan data dalam kolom berdasarkan kategori, di mana itu efektif.
Untuk menentukan efektivitas, Anda perlu mengetahui jumlah nilai unik dalam kolom dan jika kurang dari 50% dari total nilai dalam kolom, maka menggabungkan nilai dalam kategori akan efektif.
Mari kita lihat dataset:
gl_obj=gl.select_dtypes(include=['object']).copy() gl_obj.describe()
:
acd count 448533 448533 448528 unique 25100 185 447059 top VolCh 0 ! freq 3377 260438 184
* Kolom dengan tanggal dalam indeks dan tidak ditampilkan
Seperti yang Anda lihat, dari baris unik, di kolom
a dan
c , penyatuan dalam kategori efektif. Untuk kolom a, ini adalah 25.100 pengguna (jelas kurang dari 448533), untuk nilai c - 185 skala dengan "+" dan "-" (juga secara signifikan kurang dari 448533).
Kami mengoptimalkan kolom:
for col in gl_obj.columns: num_unique_values = len(gl_obj[col].unique()) num_total_values = len(gl_obj[col]) if num_unique_values / num_total_values < 0.5: converted_obj.loc[:,col] = gl_obj[col].astype('category') else: converted_obj.loc[:,col] = gl_obj[col]
Untuk memahami berapa banyak memori yang digunakan untuk kenyamanan, kami memperkenalkan fungsi:
def mem_usage(pandas_obj): if isinstance(pandas_obj,pd.DataFrame): usage_b = pandas_obj.memory_usage(deep=True).sum() else:
Dan periksa apakah optimasi itu efektif:
>>> print(' : '+mem_usage(gl_obj)) : 407.14 MB >>> print(' : '+mem_usage(converted_obj)) : 356.40 MB >>>
Seperti yang Anda lihat, keuntungan 50 MB lainnya diterima.
Sekarang, setelah memahami bahwa pengoptimalan telah menguntungkan (hal itu terjadi dan sebaliknya), kami akan menetapkan parameter dataset saat membaca untuk segera mempertimbangkan data yang sedang kami tangani:
gl = pd.read_csv('habr_2019_comments.csv', parse_dates=['b'],index_col='b',dtype ={'c':'category','a':'category','d':'object'}, encoding='UTF')
Semoga Anda cepat bekerja dengan set data!
Kode untuk mengunduh ada di
sini .