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)
작동하지만 더 효율적인 방법이 있습니까?
답변:
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/
README에서 :
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 ()에 대한 쿼리 세트를 변환하면 values () 직접보다 메모리가 더 효율적입니다. values () 메서드는 dict 목록 (키 : 값 쌍)의 쿼리 집합을 반환하므로 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"]) ## 작동하지 않습니다. 데이터 유형이 목록이 아닌 쿼리 세트와 충돌했습니다.
1 백만 행 이상의 데이터로 프로젝트에서 이것을 테스트했는데 최대 메모리가 2G에서 1G로 감소했습니다.
Django 관점에서 (저는 익숙하지 않습니다 pandas
) 이것은 괜찮습니다. 내 유일한 관심사는 레코드 수가 매우 많으면 메모리 문제가 발생할 수 있다는 것입니다. 이것이 사실이라면이 메모리 효율적인 쿼리 세트 반복자 의 라인을 따라 무언가 가 필요할 것입니다. (작성된 스 니펫은을 현명하게 사용하기 위해 약간의 재 작성이 필요할 수 있습니다 .values()
.)
.from_records()
하지 않고 list()
메모리 효율성 문제를 제거합니다.
.from_records
두 메모리 돼지를 제거하기 위해 지능형리스트없이. 예 : pd.DataFrame.from_records(qs[i].__dict__ for i in range(qs.count()))
. 하지만 "_state"
작업 을 마치면 그 성가신 칼럼 이 남습니다 . qs.values()[i]
훨씬 빠르고 깨끗하지만 캐시하는 것 같습니다.