django-pandas と pandas の違い

Django-pandas と pandas で同じ結果を得るためのコード比較

pandas初心者が、djangoでpandasを使おうとしたところ、2つの違いが分からなかったので、調べてみました。

django-pandasの場合

https://github.com/chrisdev/django-pandas/

Django-pandas 0.6.4 supports Pandas (1.2.1)

django-pandasで最新のpandasが使えるようですね

pip install django-pandas

django-pandas.io モジュールを使えばDjango QuerySetsから簡単にDataFramesが作れる

https://github.com/chrisdev/django-pandas/
>>> from students.models import Lesson
>>> from django_pandas.io import read_frame
>>> lesson_data = Lesson.objects.all()
>>> df = read_frame(lesson_data, fieldnames=['student', 'course', 'teacher', 'textbook', 'page', 'score', 'comment', 'created', 'updated', 'completed'])

おーーー、ForeignKey(course, teacher)もきれいなデータで出てきました。

インデックスも簡単に操作できるようです。上のモデルの場合だと例えば、以下の様に、「course」をインデックスに変更することもできる。

lesson_data.to_dataframe(['student', 'teacher'......省略], index_col='course'])

DataFrameManager でPandas Dataframesを使う

以下のコードをmodels.pyに追加すると、

  • to_dataframe
  • to_timeseries
  • to_pivot_table

3つのメソッドが使用できる

from django_pandas.managers import DataFrameManager #これを追加

class モデル(models.Model):

    ...

    ...

    objects = DataFrameManager() #これを追加

特定の要素を表示させてみる

「ログイン中生徒」の「レッスン一覧」と「講師名」一覧を表示させてみる

def moreChart(request):
    current_user = request.user
    queryset = Lesson.objects.filter(student=current_user.id)
    df = read_frame(queryset, fieldnames=['student', 'course', 'teacher', 'textbook', 'page', 'score', 'comment', 'created', 'updated', 'completed'])
    teacher = df.teacher
    print(df)
    print(teacher)

簡単に要素ごとに取り出せそうなので、これを可視化してみる(Bootstrapを使用した一覧表は既にあるので、担当講師別・テキスト別パイチャートを作りたい)

pandasの場合

今回は、「ログイン中のユーザー」のデータに絞り、更に「values()」と「values_list()」の両方を返して比較した、views.pyです。

import pandas as pd

def moreChart(request):
    current_user = request.user
    queryset = Lesson.objects.filter(student=current_user.id).values()
    queryset2 = Lesson.objects.filter(student=current_user.id).values_list()
    data = pd.DataFrame(queryset)
    data2 = pd.DataFrame(queryset2)
    print(data)
    print(data2)

    return render(request, 'students/djangopandas.html', {
        'data': data,
        'data2': data2
    })
    

values(): 列名が表示されている

values_list(): 列名が数字になっているので、今回はvalues()の方がよさそうですね。

ForeignKeyの「講師名・コース名」が「teacher_id」「course_id」になっちゃうのか。。。

views.pyを整理して、html表示

def moreChart(request):
    current_user = request.user
    queryset = Lesson.objects.filter(student=current_user.id).values()
    data = pd.DataFrame(queryset)
    print(data)

    return render(request, 'students/djangopandas.html', {
        'data': data.to_html(), #ここを追加
    })
{% extends "students/base.html" %}

{% block title %} My Chart {% endblock %}

{% block body %}
<div class="container">
    {{ data | safe }} # dataの後に、「| safe」を追加して整える
</div>
{% endblock %}

「safe」を追加すると、罫線を追加してくれる

現在ログイン中の、「id-2」 の生徒だけが表示されています

ついでに「describe」追記して、集計してみる(今回役に立つのはスコアのみですが。。。)

def moreChart(request):
    current_user = request.user
    queryset = Lesson.objects.filter(student=current_user.id).values()
    data = pd.DataFrame(queryset)


    return render(request, 'students/djangopandas.html', {
        'data': data.to_html(),
        'describe': data.describe().to_html() # ここを追記
    })
    
{% extends "students/base.html" %}

{% block title %} My Chart {% endblock %}


{% block body %}
<div class="container">
    {{ data | safe }}
    <hr>
    {{ describe | safe }}  # ここを追記
</div>
{% endblock %}

なんだか、いろいろ計算してくれました(笑)

売上管理や在庫管理などに利用すると、とてもよさそうですね。

赤線の上から「スコア出現回数:3回」「平均値:9点」「最低値:5点」「最高点:12点」となっています。

特定の要素に絞ってデータ表示

「ログイン中生徒さん」のレッスン一覧と、「担当講師名」表示

def moreChart(request):
    current_user = request.user
    queryset = Lesson.objects.filter(student=current_user.id)
    df = read_frame(queryset, fieldnames=['student', 'course', 'teacher', 'textbook', 'page', 'score', 'comment', 'created', 'updated', 'completed'])
    teacher = df['teacher']

    return render(request, 'students/djangopandas.html', {
        'df': df,
        'teacher': teacher
    })

pandasで特定の要素を取り出す

辞書型に変換

    data2 = data.to_dict()
    print(data2)

先ほどの「data」を辞書型に変えてみました。列ごとに辞書が生成されています。

「コメント(comment)」だけを抜き出してみます

print(data2['comment'])

ログイン中ユーザーがレッスンで使用した「テキスト(textbook)」一覧を表示します。

def moreChart(request):
    ”””中略”””
    textbooks = data['textbook'].to_list()


    return render(request, 'students/djangopandas.html', {
        'data': data.to_html(),
        'describe': data.describe().to_html(),
        'textbooks': textbooks
    })
{% extends "students/base.html" %}

{% block title %} My Chart {% endblock %}

{% block body %}
<div class="container">
    {{ data | safe }}
    <hr>
    {{ describe | safe }}
    <hr>
    {{ textbooks }}
</div>
{% endblock %}

さきほどの「describe」の下に、生徒さんがレッスンで使用したテキスト(Chart-1) がリスト表示されています。

まとめ

初心者なので、ForeignKey(講師名・コース名)を簡単に表示できたdjango-pandasがありがたいですね。pandasでもForeignKey(現在は id 表示)の名称を表示するには、どうしたらいいのかな???勉強は続く。。。

おすすめ記事

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です