2012-07-28 108 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