我将DataFrame
如下将Django QuerySet转换为pandas :
qs = SomeModel.objects.select_related().filter(date__year=2012)
q = qs.values('date', 'OtherField')
df = pd.DataFrame.from_records(q)
它有效,但是有没有更有效的方法?
我将DataFrame
如下将Django QuerySet转换为pandas :
qs = SomeModel.objects.select_related().filter(date__year=2012)
q = qs.values('date', 'OtherField')
df = pd.DataFrame.from_records(q)
它有效,但是有没有更有效的方法?
Answers:
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')))
以上是我做同一件事的方式。最有用的添加是指定您感兴趣的字段。如果它只是您感兴趣的可用字段的子集,那么我想这将提高性能。
DataFrame.from_records()
效果更好,即df = pd.DataFrame.from_records(BlogPost.objects.all().values())
。
BlogPost
应该与他相同SomeModel
吗?
Django Pandas相当巧妙地解决了这个问题: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)
df = read_frame(qs, fieldnames=['age', 'wage', 'full_name'])
在values_list()上转换queryset比直接在values()上转换内存效率更高。由于方法values()返回字典列表(键:值对)的查询集,所以values_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_list(“ A”,“ B”,“ C”,“ D”) df = pd.DataFrame(list(queryset),columns = [“ A”,“ B”,“ C”,“ D”])##这样可以节省50%的内存 #df = pd.DataFrame.from_records(queryset,columns = [“ A”,“ B”,“ C”,“ D”])##它不起作用。数据类型损坏的是查询集而不是列表。
我在大于100万行数据的项目中对此进行了测试,峰值内存从2G减少到1G。
从Django的角度(我不熟悉pandas
),这很好。我唯一关心的是,如果您有大量的记录,则可能会遇到内存问题。如果是这种情况,则必须使用这种高效内存的查询集迭代器。(如前所述,该代码段可能需要重新编写,以便您聪明地使用.values()
)。
.from_records()
和不使用的想法list()
将消除对内存效率的担忧。
.values()
返回一个ValuesQuerySet
缓存结果的,因此对于足够大的数据集,它将占用大量内存。
.from_records
没有列表理解的情况下使用,以消除这两个内存消耗。例如 pd.DataFrame.from_records(qs[i].__dict__ for i in range(qs.count()))
。但是,完成后,您会剩下那烦人的"_state"
专栏。qs.values()[i]
更快,更干净,但是我认为它可以缓存。