Python 将Django QuerySet转换为数据帧

Python 将Django QuerySet转换为数据帧,python,django,pandas,Python,Django,Pandas,我将把Django QuerySet转换为pandasDataFrame,如下所示: qs = SomeModel.objects.select_related().filter(date__year=2012) q = qs.values('date', 'OtherField') df = pd.DataFrame.from_records(q) 这是可行的,但有没有更有效的方法?从Django的角度来看(我不熟悉熊猫),这很好。我唯一担心的是,如果你有大量的记录,你可能会遇到内存问题。如

我将把Django QuerySet转换为pandas
DataFrame
,如下所示:

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

这是可行的,但有没有更有效的方法?

从Django的角度来看(我不熟悉熊猫),这很好。我唯一担心的是,如果你有大量的记录,你可能会遇到内存问题。如果是这样的话,有必要采取类似的措施。(编写的代码段可能需要进行一些重写,以允许您智能地使用
.values()


以上是我如何做同样的事情。最有用的补充是指定您感兴趣的字段。如果它只是您感兴趣的可用字段的一个子集,那么我想这将提高性能。

您可能可以使用model\u 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()

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)

在值上转换查询集\u list()比直接在值()上转换查询集更节省内存。由于方法values()返回dict(键:值对)列表的查询集,因此values\u list()只返回元组列表(纯数据)。它将节省大约50%的内存,只需在调用pd.DataFrame()时设置列信息

方法1: queryset=models.xxx.objects.values(“A”、“B”、“C”、“D”) df=pd.DataFrame(list(queryset))消耗大量内存 #df=pd.DataFrame.from_records(queryset)##可以工作,但在内存使用上没有太大变化 方法2: queryset=models.xxx.objects.values\u列表(“A”、“B”、“C”、“D”) df=pd.DataFrame(列表(queryset),列=[“A”、“B”、“C”、“D”])##这将节省50%的内存 #df=pd.DataFrame.from_记录(queryset,columns=[“A”、“B”、“C”、“D”])35;#它不起作用。数据类型为queryset not list时崩溃。
我在我的项目中使用了>100万行数据进行了测试,峰值内存从2G减少到1G。

Hi@FrancoMariluis,很抱歉,这超出了主题:您是否在django项目中使用pandas。通过django web应用程序使用“使用matplotlib打印”显示图形。这是一个有效的解决方案吗?谢谢。您好,在Django中显示图形,我正在使用Django chartit,它工作得很好,但是我正在考虑使用matplotlib,它会给我带来更多的灵活性。看起来很简单,它工作得很好。有什么特别的问题吗?你现在的方式有什么问题吗?你有什么特别担心的吗?这是我第一次(也是唯一一次!)的方法,但因为我对pandas还不太熟悉,我想看看是否有其他方法,但这似乎是一个好方法。使用“list()”似乎已被弃用(我使用的是pandas 0.12)。使用
DataFrame.from_records()
效果更好,即
df=pd.DataFrame.from_records(BlogPost.objects.all().values())
。如果使用OP-question中的名称,会更清楚。例如,
BlogPost
是否应该与他的
SomeModel
相同?嗨,有没有办法排除数据框架中不需要的列?@GregoryGoltsov的想法是使用
.from_records()
而不使用
列表()
将消除内存效率问题。内存效率问题位于Django端。返回一个缓存结果的
ValuesQuerySet
,因此对于足够大的数据集,它将非常占用内存。啊,是的。您必须索引到queryset并使用
.from\u records
,而无需列表理解来消除这两个内存占用。e、 g.
pd.DataFrame.from_记录(qs[i]。u dict_uuu)用于范围内的i(qs.count())
。但当你完成时,你就只剩下那讨厌的
“\u state”
列了
qs.values()[i]
更快更干净,但我认为它可以缓存。Django Pandas如何处理大型数据集?这一行让我害怕,因为我认为这意味着整个数据集将立即加载到内存中。@Ada要使用指定的字段名创建一个数据帧:
df=read\u frame(qs,fieldnames=['age','wage','full\u name'])
对于那些在这个美好的未来想知道我在干什么的人,这里有一个更永久的链接,指向当时的源代码:
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)
Method 1: queryset = models.xxx.objects.values("A","B","C","D") df = pd.DataFrame(list(queryset)) ## consumes much memory #df = pd.DataFrame.from_records(queryset) ## works but no much change on memory usage Method 2: queryset = models.xxx.objects.values_list("A","B","C","D") df = pd.DataFrame(list(queryset), columns=["A","B","C","D"]) ## this will save 50% memory #df = pd.DataFrame.from_records(queryset, columns=["A","B","C","D"]) ##It does not work. Crashed with datatype is queryset not list.