django中使用pandas Django-pandas

在django中使用pandas操作django的ORM查询出来的QuerySet对象,可以使用插件django-pandas。

截止教程书写时间,django-pandas已发布到0.6.1。

依赖:django>=1.4.5

          Django-model-utils >=1.4.0

          Pandas >=0.12.0

           当然,还需要numpy

用法:

1、IO模块:

该django-pandas.io模块提供了一些方便的方法,以便从django的查询集转换成DataFrames的创建。

read_frame

参数:

l   qs :一个django的QuerySet。

l   fieldnames :用于创建DataFrame的模型字段名称列表。可以使用双下划线指定另一个model中的相关字段,以通常的Django方式跨越关系。

l   index_col:使用指定用于DataFrame索引的字段名称。如果索引字段不在fieldnames参数中,则将会添加,注意这里的字段必须为该model里的字段。

l   coerce_float:Boolean(布尔值),默认为True。尝试将值转换为非字符串,将非数字对象(如decimal.Decimal)转化为浮点类型。

   Eg:

model.py

class Img_info(models.Model):
    '''
    图片信息表
    '''
    img_name = models.CharField(max_length=128, verbose_name="图片名")
    img = models.ImageField(upload_to="img", verbose_name="图片")

    class Meta:
        db_table = "img_info"


class Product_score(models.Model):
    '''
    图片打分表
    '''
    img_of = models.ForeignKey(Img_info, on_delete=models.CASCADE, verbose_name="图片")
    scoring_staff = models.CharField(max_length=32, verbose_name="打分员")
    score_num = models.FloatField(verbose_name="分数")

    class Meta:
        db_table = "product_score"

views.py

1、直接转化

from django_pandas.io import read_frame


def tset(request):
    qs = Product_score.objects.all()
    qs_dataframe = read_frame(qs=qs)
    print(qs_dataframe)
    return HttpResponse('ok')

运行结果:

    id               img_of scoring_staff  score_num
0   15  Img_info object (5)           测试1       22.0
1   16  Img_info object (6)           测试1       23.0
2   17  Img_info object (7)           测试1       24.0
3   18  Img_info object (8)           测试1       25.0
4   19  Img_info object (9)           测试1       26.0
5   20  Img_info object (5)           测试2       22.0
6   21  Img_info object (6)           测试2       23.0
7   22  Img_info object (7)           测试2       24.0
8   23  Img_info object (8)           测试2       25.0
9   24  Img_info object (9)           测试2       26.0
10  25  Img_info object (5)           测试3       22.0
11  26  Img_info object (6)           测试3       23.0
12  27  Img_info object (7)           测试3       24.0
13  28  Img_info object (8)           测试3       25.0

2、跨关联表显示

views.py

from django_pandas.io import read_frame


def tset(request):
    qs = Product_score.objects.all()
    qs_dataframe = read_frame(qs=qs,fieldnames=['img_of__img_name', 'scoring_staff', 'score_num'])
    print(qs_dataframe)
    return HttpResponse('ok')

运行结果:

   img_of__img_name scoring_staff  score_num
0               士大夫           测试1       22.0
1               士大夫           测试2       22.0
2               士大夫           测试3       22.0
3               54撒           测试1       23.0
4               54撒           测试2       23.0
5               54撒           测试3       23.0
6               撒旦撒           测试1       24.0
7               撒旦撒           测试2       24.0
8               撒旦撒           测试3       24.0
9              撒旦撒2           测试1       25.0
10             撒旦撒2           测试2       25.0
11             撒旦撒2           测试3       25.0
12               24           测试1       26.0
13               24           测试2       26.0

3、指定索引

views.py

def tset(request):
    qs = Product_score.objects.all()
    qs_dataframe = read_frame(qs=qs,fieldnames=['img_of__img_name', 'scoring_staff', 'score_num'],index_col='id')
    print(qs_dataframe)
    return HttpResponse('ok')

运行结果:

   img_of__img_name scoring_staff  score_num
id                                          
15              士大夫           测试1       22.0
20              士大夫           测试2       22.0
25              士大夫           测试3       22.0
16              54撒           测试1       23.0
21              54撒           测试2       23.0
26              54撒           测试3       23.0
17              撒旦撒           测试1       24.0
22              撒旦撒           测试2       24.0
27              撒旦撒           测试3       24.0
18             撒旦撒2           测试1       25.0
23             撒旦撒2           测试2       25.0
28             撒旦撒2           测试3       25.0
19               24           测试1       26.0
24               24           测试2       26.0

2、DataFrameManager

django-pandas提供了一个自定义管理器,可用于要呈现为pandas Dataframes的模型。该DataFrameManager管理器提供to_dataframe返回你模型查询集(queryset )为pandas的DataFrame。要使用DataFrameManager,首先覆盖model定义中的默认管理器(objects)。

这将使您可以访问以下QuerySet方法:

l   to_dataframe  从QuerySet返回DataFrame

l   to_timeserie  用于创建时间序列的便捷方法,即DataFrame索引是DateTime或PeriodIndex的实例

l   to_pivot_table 从QuerySet创建数据透视表的便捷方法

to_dataframe

l   fieldnames :用于创建DataFrame的模型字段名称列表。可以使用双下划线指定另一个model中的相关字段,以通常的Django方式跨越关系。

l   index:使用指定用于DataFrame索引的字段名称。如果索引字段不在fieldnames参数中,则将会添加,注意这里的字段必须为该model里的字段。

l   coerce_float:Boolean(布尔值),默认为True。尝试将值转换为非字符串,将非数字对象(如decimal.Decimal)转化为浮点类型。

eg:

models.py

class Img_info(models.Model):
    '''
    图片信息表
    '''
    img_name = models.CharField(max_length=128, verbose_name="图片名")
    img = models.ImageField(upload_to="img", verbose_name="图片")

    class Meta:
        db_table = "img_info"


class Product_score(models.Model):
    '''
    图片打分表
    '''
    img_of = models.ForeignKey(Img_info, on_delete=models.CASCADE, verbose_name="图片")
    scoring_staff = models.CharField(max_length=32, verbose_name="打分员")
    score_num = models.FloatField(verbose_name="分数")
    objects = DataFrameManager()

    class Meta:
        db_table = "product_score"

views.py

def tset(request):
    qs = Product_score.objects.all()
    qs_dataframe = qs.to_dataframe(fieldnames=['img_of__img_name', 'scoring_staff', 'score_num'], index='id', coerce_float=True)
    print(qs_dataframe)
    return HttpResponse('ok')

运行结果:

   img_of__img_name scoring_staff  score_num
id                                          
15              士大夫           测试1       22.0
20              士大夫           测试2       22.0
25              士大夫           测试3       22.0
16              54撒           测试1       23.0
21              54撒           测试2       23.0
26              54撒           测试3       23.0
17              撒旦撒           测试1       24.0
22              撒旦撒           测试2       24.0
27              撒旦撒           测试3       24.0
18             撒旦撒2           测试1       25.0
23             撒旦撒2           测试2       25.0
28             撒旦撒2           测试3       25.0
19               24           测试1       26.0
24               24           测试2       26.0

您可以使用过滤器和排除:

筛选出分数大于23的

views.py

def tset(request):
    qs = Product_score.objects.all()
    qs_dataframe = qs.filter(score_num__gt=23).to_dataframe(fieldnames=['img_of__img_name', 'scoring_staff', 'score_num'], index='id', coerce_float=True)
    print(qs_dataframe)
    return HttpResponse('ok')

运行结果:

   img_of__img_name scoring_staff  score_num
id                                          
17              撒旦撒           测试1       24.0
18             撒旦撒2           测试1       25.0
19               24           测试1       26.0
22              撒旦撒           测试2       24.0
23             撒旦撒2           测试2       25.0
24               24           测试2       26.0
27              撒旦撒           测试3       24.0
28             撒旦撒2           测试3       25.0

to_pivot_table

  • fieldnames:用于创建DataFrame的模型字段名称列表。可以使用双下划线指定另一个model中的相关字段,以通常的Django方式跨越关系。
  • values:要聚合的列,可选
  • rows : 要分组的列名称或数组的列表,在数据透视表的x轴上分组的键
  • cols : 要分组的列名称或数组的列表,在数据透视表的y轴上分组的键
  • aggfunc : function,默认numpy.mean或函数列表,如果传递的函数列表,生成的数据透视表将具有分层列,其顶层是函数名称(从函数对象本身推断)
  • fill_value : 标量,默认无,用于替换缺失值的值
  • margin : boolean,默认为False,添加所有行/列(例如,对于小计/总计)
  • dropna:布尔值,默认为True,去除NaN值

views.py

def tset(request):
    qs = Product_score.objects.all()
    data_df_to_pivot_table = qs.to_pivot_table(
        values='score_num', rows=['img_of__img_name'], cols=['scoring_staff'], fieldnames=['img_of__img_name', 'scoring_staff', 'score_num'], margins=True)
    print(data_df_to_pivot_table)
    return HttpResponse('ok')

运行结果:

scoring_staff      测试1   测试2   测试3        All
img_of__img_name                             
24                26.0  26.0   NaN  26.000000
54撒               23.0  23.0  23.0  23.000000
士大夫               22.0  22.0  22.0  22.000000
撒旦撒               24.0  24.0  24.0  24.000000
撒旦撒2              25.0  25.0  25.0  25.000000
All               24.0  24.0  23.5  23.857143

 

posted @ 2019-08-12 22:37  xsan  阅读(9018)  评论(0编辑  收藏  举报