DataFrame次のように、DjangoQuerySetをパンダに変換します。
qs = SomeModel.objects.select_related().filter(date__year=2012)
q = qs.values('date', 'OtherField')
df = pd.DataFrame.from_records(q)
それは機能しますが、より効率的な方法はありますか?
DataFrame次のように、DjangoQuerySetをパンダに変換します。
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のリスト(key:valueのペア)のクエリセットを返すため、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()するaValuesQuerySetを返すため、十分な大きさのデータセットの場合、メモリを大量に消費します。
.from_records必要があります。例: pd.DataFrame.from_records(qs[i].__dict__ for i in range(qs.count()))。しかし、"_state"完了すると、その厄介な列が残ります。qs.values()[i]はるかに高速でクリーンですが、キャッシュすると思います。