Saya akan mengubah Django QuerySet menjadi panda DataFrame
sebagai berikut:
qs = SomeModel.objects.select_related().filter(date__year=2012)
q = qs.values('date', 'OtherField')
df = pd.DataFrame.from_records(q)
Berhasil, tetapi apakah ada cara yang lebih efisien?
Jawaban:
import pandas as pd import datetime from myapp.models import BlogPost df = pd.DataFrame(list(BlogPost.objects.all().values())) df = pd.DataFrame(list(BlogPost.objects.filter(date__gte=datetime.datetime(2012, 5, 1)).values())) # limit which fields df = pd.DataFrame(list(BlogPost.objects.all().values('author', 'date', 'slug')))
Di atas adalah bagaimana saya melakukan hal yang sama. Penambahan yang paling berguna adalah menentukan bidang mana yang Anda minati. Jika hanya sebagian dari bidang yang tersedia yang Anda minati, saya rasa ini akan memberikan peningkatan kinerja.
sumber
DataFrame.from_records()
bekerja lebih baik, yaitudf = pd.DataFrame.from_records(BlogPost.objects.all().values())
.BlogPost
harus sama dengan miliknyaSomeModel
?Django Panda memecahkan ini dengan agak rapi: https://github.com/chrisdev/django-pandas/
Dari README:
class MyModel(models.Model): full_name = models.CharField(max_length=25) age = models.IntegerField() department = models.CharField(max_length=3) wage = models.FloatField() from django_pandas.io import read_frame qs = MyModel.objects.all() df = read_frame(qs)
sumber
df = read_frame(qs, fieldnames=['age', 'wage', 'full_name'])
Mengonversi queryset pada values_list () akan lebih menghemat memori daripada pada values () secara langsung. Karena metode values () mengembalikan queryset dari daftar dict (key: value pairs), values_list () hanya mengembalikan daftar tuple (data murni). Ini akan menghemat sekitar 50% memori, hanya perlu mengatur informasi kolom ketika Anda memanggil pd.DataFrame ().
Saya menguji ini pada proyek saya dengan> 1 juta baris data, memori puncak berkurang dari 2G menjadi 1G.
sumber
Dari perspektif Django (saya tidak paham
pandas
) ini bagus. Satu-satunya kekhawatiran saya adalah jika Anda memiliki jumlah record yang sangat besar, Anda mungkin mengalami masalah memori. Jika ini masalahnya, sesuatu yang sejalan dengan iterator queryset hemat memori ini akan diperlukan. (Cuplikan seperti yang tertulis mungkin memerlukan beberapa penulisan ulang untuk memungkinkan penggunaan cerdas Anda.values()
).sumber
.from_records()
dan tidak menggunakanlist()
akan menghilangkan masalah efisiensi memori..values()
mengembalikan hasilValuesQuerySet
yang di-cache, jadi untuk kumpulan data yang cukup besar, ini akan membutuhkan banyak memori..from_records
tanpa pemahaman daftar untuk menghilangkan kedua memori hog. mispd.DataFrame.from_records(qs[i].__dict__ for i in range(qs.count()))
. Tapi Anda ditinggalkan dengan"_state"
kolom yang mengganggu itu ketika Anda selesai.qs.values()[i]
jauh lebih cepat dan lebih bersih, tapi saya pikir itu cache.Anda mungkin bisa menggunakan model_to_dict
import datetime from django.forms import model_to_dict pallobjs = [ model_to_dict(pallobj) for pallobj in PalletsManag.objects.filter(estado='APTO_PARA_VENTA')] df = pd.DataFrame(pallobjs) df.head()
sumber