2012-07-28 87 views
45

我要一個Django的QuerySet轉換爲大熊貓DataFrame如下:轉換Django的查詢集到大熊貓數據幀

qs = SomeModel.objects.select_related().filter(date__year=2012) 
q = qs.values('date', 'OtherField') 
df = pd.DataFrame.from_records(q) 

它的工作原理,但有一個更有效的方法?

+0

嗨@FrancoMariluis,關於這一點話題的遺憾:是你在django項目中使用熊貓。您可以通過django web應用程序使用「使用matplotlib繪圖」來顯示圖形。是您的有效解決方案嗎?謝謝。 – danihp 2012-07-28 19:09:22

+0

嗨,在Django中顯示圖形我使用django-chartit,它工作正常,但我正在考慮使用matplotlib,這會給我更多的靈活性 – 2012-07-29 00:55:40

+0

看起來像一個好方法。 – 2012-08-14 19:15:00

回答

2

從Django的角度來看(我不熟悉pandas)這很好。我唯一擔心的是如果你有很多記錄,你可能會遇到內存問題。如果是這種情況,則需要沿着這個memory efficient queryset iterator的方向行事。 (所寫的片段可能需要重寫才能讓您巧妙地使用.values())。

+0

@ GregoryGoltsov使用'.from_records()'而不使用'list()'的想法將消除內存效率問題。 – hobs 2014-12-16 22:29:07

+1

內存效率問題在Django方面。 ['.values()'](https://docs.djangoproject.com/en/1.7/ref/models/querysets/#django.db.models.query.QuerySet.values)返回一個'ValuesQuerySet',它緩存結果,所以對於一個足夠大的數據集,這將是相當大的內存密集型。 – 2014-12-17 22:41:19

+0

啊,是的。你必須索引到查詢集*和*使用沒有列表理解的'.from_records'來消除這兩個內存豬。例如'pd.DataFrame.from_records(qs [i] .__ dict__ for i in range(qs.count()))''。但是當你完成之後,你只剩下那個惱人的「_state」列。 'qs.values()[i]'更快更乾淨,但我認爲它會緩存。 – hobs 2014-12-17 23:02:55

40
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'))) 

以上是我如何做同樣的事情。最有用的補充是指定你感興趣的領域。如果它只是你感興趣的可用字段的一個子集,那麼這會讓我想象的性能提升。

+16

使用'list()'似乎已被棄用(我在熊貓0.12)。使用'DataFrame.from_records()'效果更好,即''df = pd.DataFrame.from_records(BlogPost.objects.all()。values())''。 – gregoltsov 2013-10-28 01:25:02

+0

如果使用OP問題中的名稱,這將更加清楚。例如,BlogPost應該和他的SomeModel一樣嗎? – 2017-07-26 18:39:31

0

您也許可以使用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() 
9

Django的大熊貓解決了這個相當整齊:https://github.com/chrisdev/django-pandas/

自述:

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) 
+2

Django Pandas如何處理大型數據集? https://github.com/chrisdev/django-pandas/blob/master/django_pandas/io.py#L107這一行讓我感到害怕,因爲我認爲這意味着整個數據集會一次加載到內存中。 – 2016-11-04 11:06:45