Ich werde ein Django QuerySet DataFrame
wie folgt in ein Pandas konvertieren :
qs = SomeModel.objects.select_related().filter(date__year=2012)
q = qs.values('date', 'OtherField')
df = pd.DataFrame.from_records(q)
Es funktioniert, aber gibt es einen effizienteren Weg?
Antworten:
Das Obige ist, wie ich das gleiche mache. Die nützlichste Ergänzung ist die Angabe der Felder, an denen Sie interessiert sind. Wenn es sich nur um eine Teilmenge der verfügbaren Felder handelt, an denen Sie interessiert sind, würde dies meiner Meinung nach zu einer Leistungssteigerung führen.
quelle
DataFrame.from_records()
funktioniert besser, dhdf = pd.DataFrame.from_records(BlogPost.objects.all().values())
.BlogPost
angenommen , dasselbe wie seine seinSomeModel
?Django Pandas löst dies ziemlich ordentlich: https://github.com/chrisdev/django-pandas/
Aus der README:
quelle
df = read_frame(qs, fieldnames=['age', 'wage', 'full_name'])
Das Konvertieren des Abfragesatzes in values_list () ist speichereffizienter als in values () direkt. Da die Methode values () eine Abfragemenge der Liste von dict (Schlüssel: Wertepaare) zurückgibt, gibt values_list () nur die Liste von Tupeln (reine Daten) zurück. Dies spart etwa 50% Speicherplatz. Sie müssen lediglich die Spalteninformationen festlegen, wenn Sie pd.DataFrame () aufrufen.
Ich habe dies in meinem Projekt mit> 1 Million Zeilendaten getestet, der Spitzenspeicher ist von 2G auf 1G reduziert.
quelle
Aus der Django-Perspektive (mit der ich nicht vertraut bin
pandas
) ist dies in Ordnung. Meine einzige Sorge ist, dass bei einer sehr großen Anzahl von Datensätzen Speicherprobleme auftreten können. Wenn dies der Fall wäre, wäre etwas in der Art dieses speichereffizienten Abfragesatz-Iterators erforderlich. (Das geschriebene Snippet muss möglicherweise neu geschrieben werden, damit Sie es intelligent verwenden können..values()
)quelle
.from_records()
und nicht zu verwendenlist()
, beseitigt die Bedenken hinsichtlich der Speichereffizienz..values()
Gibt einValuesQuerySet
Ergebnis zurück, das die Ergebnisse zwischenspeichert. Für ein ausreichend großes Dataset ist es also ziemlich speicherintensiv..from_records
ohne die Liste Verständnis beiden Speicherfresser zu eliminieren. zBpd.DataFrame.from_records(qs[i].__dict__ for i in range(qs.count()))
. Aber"_state"
wenn Sie fertig sind, bleibt Ihnen diese nervige Kolumne.qs.values()[i]
ist viel schneller und sauberer, aber ich denke, es wird zwischengespeichert.Sie können möglicherweise model_to_dict verwenden
quelle