Django QuerySet को पंडों में परिवर्तित करना DataFrame


91

मैं एक Django QuerySet को एक पांडा के DataFrameरूप में इस प्रकार परिवर्तित करने जा रहा हूं :

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

यह काम करता है, लेकिन क्या एक अधिक कुशल तरीका है?


हाय @FrancoMariluis, इस विषय के बारे में खेद है: क्या आप django परियोजनाओं में पांडा का उपयोग कर रहे हैं। आप django वेब अनुप्रयोगों के माध्यम से "प्लॉटिंग विद मैटप्लोटलिब" का उपयोग करके ग्राफिक्स दिखाते हैं। क्या आपके लिए एक वैध समाधान है? धन्यवाद।
दानी हेर्रे

नमस्ते, Django में ग्राफिक्स दिखाने के लिए मैं django-chartit का उपयोग कर रहा हूं, जो ठीक काम करता है, लेकिन मैं matplotlib का उपयोग करने के बारे में सोच रहा हूं, जो मुझे और अधिक लचीलापन देगा
फ्रेंको मारिलुइस

बहुत सीधा लगता है, और यह काम करता है। कोई विशेष चिंता?
दिमित्री शेवचेंको

आपके द्वारा अभी प्राप्त किए गए तरीके में क्या गलत है? क्या आपको कोई विशेष चिंता है?
बुरहान खालिद

यह मेरा पहला (और केवल!) दृष्टिकोण था, लेकिन चूंकि मैं पांडा के लिए काफी नया हूं, इसलिए मैं यह देखना चाहता था कि क्या कोई और तरीका है, लेकिन यह एक अच्छा लगता है।
फ्रेंको मैरिलिउस

जवाबों:


87
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')))

ऊपर मैं वही काम करता हूं। सबसे उपयोगी जोड़ यह निर्दिष्ट कर रहा है कि आप किन क्षेत्रों में रुचि रखते हैं। यदि यह केवल उन उपलब्ध फ़ील्डों का एक सबसेट है जिसमें आप रुचि रखते हैं, तो यह एक प्रदर्शन को बढ़ावा देगा जिसकी मैं कल्पना करता हूं।


37
'सूची ()' के प्रयोग से पदावनत किया गया लगता है (मैं पांडा 0.12 पर हूँ)। का उपयोग करते हुए DataFrame.from_records()काम करता है बेहतर, यानी df = pd.DataFrame.from_records(BlogPost.objects.all().values())
gregoltsov

2
यह अधिक स्पष्ट होगा यदि यह ओपी प्रश्न से नामों का उपयोग करता है। उदाहरण के लिए, क्या BlogPostउसके जैसा ही माना जाता है SomeModel?
हैक-आर

नमस्ते, क्या डेटाफ़्रेम में किसी कॉलम को बाहर करने की ज़रूरत नहीं है?
विवर

19

Django पंडों ने बड़े करीने से हल किया: 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)

11
Django पांडस बड़े डेटासेट के साथ कैसे व्यवहार करता है? github.com/chrisdev/django-pandas/blob/master/django_pandas/… यह पंक्ति मुझे डराती है, क्योंकि मुझे लगता है कि इसका मतलब है कि संपूर्ण डेटासेट एक ही बार में मेमोरी में लोड हो जाएगा।
एडम बार्न्स 11

: @Ada निर्दिष्ट फ़ील्ड नाम का उपयोग कर एक DataFrame बनाने के लिएdf = read_frame(qs, fieldnames=['age', 'wage', 'full_name'])
Gathide

इस अद्भुत भविष्य में आपमें से जो सोच रहे हैं कि मैं इस बारे में था, उस समय स्रोत का अधिक स्थायी लिंक यहां है: github.com/chrisdev/django-pandas/blob/…
एडम

9

सीधे मूल्यों () पर की तुलना में values_list () पर क्वेरी को कनवर्ट करना अधिक मेमोरी कुशल होगा। चूंकि विधि मान () तानाशाह (कुंजी: मूल्य जोड़े) की सूची का एक क्वेरीसेट देता है, मान_लिस्ट () केवल टपल (शुद्ध डेटा) की सूची देता है। यह लगभग 50% मेमोरी बचाएगा, बस आपको कॉलम की जानकारी सेट करने की आवश्यकता है जब आप pd.DataFrame () कहते हैं।

विधि 1:
    क्वेरीसेट = model.xxx.objects.values ​​("ए", "बी", "सी", "डी")
    df = pd.DataFrame (सूची (क्वेरीसेट)) ## बहुत स्मृति का उपभोग करता है
    #df = pd.DataFrame.from_records (क्वेरीसेट) ## काम करता है लेकिन स्मृति उपयोग पर कोई बहुत अधिक परिवर्तन नहीं

विधि 2:
    क्वेरीसेट = model.xxx.objects.values_list ("ए", "बी", "सी", "डी")
    df = pd.DataFrame (सूची (क्वेरीसेट), कॉलम = ["A", "B", "C", "D"]) ## यह 50% मेमोरी बचाएगा
    #df = pd.DataFrame.from_records (क्वेरीसेट, कॉलम = ["ए", "बी", "सी", "डी"]) ## यह काम नहीं करता है। डेटाटाइप के साथ क्रैश की गई सूची नहीं है।

मैंने अपने प्रोजेक्ट पर> 1 मिलियन पंक्तियों के डेटा के साथ यह परीक्षण किया, पीक मेमोरी 2G से 1G तक कम हो जाती है।


2

Django के दृष्टिकोण से (मैं परिचित नहीं हूं pandas) यह ठीक है। मेरी एकमात्र चिंता यह है कि यदि आपके पास बहुत बड़ी संख्या में रिकॉर्ड हैं, तो आप स्मृति समस्याओं में भाग सकते हैं। यदि ऐसा होता, तो इस मेमोरी कुशल क्वेरीसेट इटरेटर की तर्ज पर कुछ करना आवश्यक होता। (लिखित रूप में स्निपेट को आपके स्मार्ट उपयोग के लिए अनुमति देने के लिए कुछ पुनर्लेखन की आवश्यकता हो सकती है .values())।


@ ग्रेगरीगोल्तसोव का उपयोग करने .from_records()और नहीं करने का विचार list()स्मृति दक्षता की चिंता को खत्म कर देगा।
होब्स

1
मेमोरी दक्षता चिंता Django की ओर है। जो .values()एक ValuesQuerySetकैश परिणाम देता है, इसलिए एक बड़े पर्याप्त डेटासेट के लिए, यह काफी स्मृति-गहन होने वाला है।
डेविड आइक

1
आह हाँ। आपको दोनों मेमोरी हॉग को खत्म करने के लिए सूची समझ के बिना क्वेरी में इंडेक्स और उपयोग .from_recordsकरना होगा। उदा pd.DataFrame.from_records(qs[i].__dict__ for i in range(qs.count()))"_state"जब आप काम कर रहे हों तो आप उस कष्टप्रद कॉलम से बचे रहें । qs.values()[i]बहुत तेज और क्लीनर है, लेकिन मुझे लगता है कि यह कैश है।
होब्स

1

आप शायद 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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.