在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