<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          神器Jinja2,用 Python 快速生成分析報告!

          共 9671字,需瀏覽 20分鐘

           ·

          2021-09-10 13:38

          點擊上方“Python爬蟲與數(shù)據(jù)挖掘”,進行關注

          回復“書籍”即可獲贈Python從入門到進階共10本電子書

          夜闌臥聽風吹雨,鐵馬冰河入夢來。

          大家好,我是早起。

          在之前的文章中,我們使用 Python 開發(fā)了一個簡單的基金購買策略的回測系統(tǒng)。在代碼執(zhí)行完畢后,會生成一系列的結果,包含大量圖片、表格如下

          此時如果一個一個查看的話便十分低效,如果能使用一個文件把全部輸出結果都保存將會大大提高體驗。

          首先想到的當然是 PDF 格式,利用 Python 操作 PDF 也是之前文章分享過很多,想必利用表格+圖片生成一個新的PDF并不困難。研究了一番后,發(fā)現(xiàn)確實不難,但是太繁瑣了,并且 PDF 涉及格式、分頁等,如果沒有調(diào)整好可能會將一張圖片放在兩頁或者一頁只有一張圖其余全是空白,十分影響美觀,由于我每次產(chǎn)生的結果并不固定,因此很難找到一個通用的模版,遂放棄。

          PDF 既然不行,Word就更不用考慮了,所以只能選擇 html 格式,雖然跨平臺性沒有 PDF 好,但是勝在排版簡單,不需要考慮分頁處理。基于 Python 生成 html 有很多成熟的 web 開發(fā)框架可以選擇,但為了整體過程不太復雜,最終選擇 Jinja2 來實現(xiàn)這個需求。



          02

          jinja2



          Jinja2 是一個 Python 的功能齊全的模板引擎,簡單來說就是我們將 html 的主要部分寫好,將需要填充的內(nèi)容空出來,這樣就是一個模版,之后就可以使用 Jinja2 來自動將模版文件填充,形成一個完整的 html 文件。

          填入文字

          首先我們需要制作一個最簡單的模版文件template.html,內(nèi)容如下

          <html>
          <head>
              <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
              <title>report</title>
          </head>
          <h1>基金策略回測報告</h1>
              <body>
              <h2>一、策略詳情</h2>
              <p>策略描述:{{ strategy_name }}</p>
              <p>回測時間段:{{ start_time }} --> {{ end_time }}  </p>
              <p>初始本金:{{ money }}</p>
              </body>
          </html>

          直接打開如下

          其中被 {{}} 包起來的變量,就是我們需要用 Python 傳遞給模版的,很明顯上方代碼缺少四個變量,下面是 Python 代碼

          import pandas as pd
          from jinja2 import Environment, FileSystemLoader


          data = {'strategy_name''第一個策略',
                  'start_time''2020-01-01',
                  'end_time''2021-06-01',
                  'money'20000}

          env = Environment(loader=FileSystemLoader('./'))

          template = env.get_template('template.html')

          with open("out.html"'w+', encoding='utf-8'as f:
              out = template.render(strategy_name=data['strategy_name'],
                                    start_time=data['start_time'],
                                    end_time=data['end_time'],
                                    money=data['money'])
              f.write(out)
              f.close()

          在上面的代碼中,我們使用env.get_template('template.html')讀取模版文件,并將需要需要傳入的數(shù)據(jù)寫入字典中,并將 value 通過template.render傳給模版并渲染輸出,現(xiàn)在打開生成的 out.html 內(nèi)容如下

          可以看到目標位置的文字都被正確填充,當然填入文字是最基本的操作,下面繼續(xù)介紹如何自動創(chuàng)建表格。

          填入表格

          其實填入表格和填入文字本質(zhì)上是一樣的,只不過需要使用循環(huán)來操作,例如將回測指標匯總.xlsx添加到html中

          首先在模版文件中創(chuàng)建一個表格

          <h2>二、回測結果</h2>

              <table border="1" width = "40%" cellspacing='0' cellpadding='0'>
              <tr>
                  <th>基金名稱</th>
                  <th>總投入本金</th>
                  <th>總收益率</th>
                  <th>最大回測率</th>
              </tr>

              {% for item in items %}
              <tr align='center'>
                  <td>{{ item.基金名稱 }}</td>
                  <td>{{ item.消耗本金 }}</td>
                  <td>{{ item.總收益率 }}</td>
                  <td>{{ item.最大回撤率 }}</td>
              </tr>
              {% endfor%}
              </table>

          在上面的代碼中,我們使用創(chuàng)建了一個table,并將表頭寫好,將 cell 內(nèi)容設置為待填充,注意在jinja2中的循環(huán)是通過{% %}來完成的。

          例如{% for item in items %} 就需要我們傳入一個字典形式 items ,并且里面包含基金名稱、消耗本金、總收益率、最大回撤率四個key,此時 Python 代碼修改如下

          import pandas as pd
          from jinja2 import Environment, FileSystemLoader

          df = pd.read_excel('回測指標匯總.xlsx')
          df['消耗本金'] = df['消耗本金'].astype(str) + ' 元'
          df['最大回撤率'] = df['最大回撤率'].astype(str) + '%'
          df['總收益率'] = df['總收益率'].astype(str) + '%'
          data = df.to_dict('records')

          results = {}
          results.update({'strategy_name''第一個策略',
                          'start_time''2020-01-01',
                          'end_time''2021-06-01',
                          'money'20000,
                          'items': data})

          env = Environment(loader=FileSystemLoader('./'))

          template = env.get_template('template.html')

          with open("out.html"'w+', encoding='utf-8'as f:
              out = template.render(strategy_name=results['strategy_name'],
                                    start_time=results['start_time'],
                                    end_time=results['end_time'],
                                    money=results['money'],
                                    items = results['items'])
              f.write(out)
              f.close()

          需要注意的是因為我們需要循環(huán)操作,所以傳入的 items 就需要是可迭代的,但又需要根據(jù)關鍵字匹配值,所以可以將每一行數(shù)據(jù)轉換為字典,并放在 list 中,這一步可以使用 pandas 讀取excel并直接使用df.to_dict('records')完成(吹一波pandas現(xiàn)在執(zhí)行上面的代碼,并打開輸出后的 html

          可以看到,Excel的全部內(nèi)容都被正確的填入,下面介紹如何填入圖片。

          填入圖片

          其實 html 展示圖片就是通過<a>標簽超鏈接指向圖片地址,所以本質(zhì)上和填充文字差不多,只需要在模版文件中把本地圖片地址預留出來,之后使用 jinja2 傳入即可,例如可以在模版中添加以下內(nèi)容

          <a name="{{ 回測指標 }}"> <img src="{{ indicator }}" width="850"></a>

          此時在 Python 代碼中指定indicator圖片路徑并傳入即可

          indicator = 'images/' + '回測指標.png'
          with open("out.html"'w+', encoding='utf-8'as f:
              out = template.render(strategy_name=results['strategy_name'],
                                    start_time=results['start_time'],
                                    end_time=results['end_time'],
                                    money=results['money'],
                                    items = results['items'],
                                    indicator = indicator)
              f.write(out)
              f.close()

          執(zhí)行后即可正確展示圖片如下

          當然我們的圖片不止一張,可以像上面插入表格一樣將圖片地址循環(huán)填入即可,本文不再贅述,感興趣讀者可以自己研究。

          修改樣式

          當然,默認生成的 html 樣式可能不夠好看,我們也可以進一步添加一點CSS代碼來調(diào)整,為了簡化可以直接將代碼寫在標簽中

              <style type="text/css">
              h1 {margin-left20px}
              h2 {margin-left20px;
                  font-size19px;
                  font-weight: bold;
                  display: inline-block;
                  padding-left10px;
                  border-left5px solid #916dd5;}
              h3 {margin-left20px}
              h4 {margin-left20px;
                  margin-bottom: -5px}
              table {margin-left20px;
                     margin-top5px;
                     margin-bottom5px}
              p {margin-left20px}
              a {margin-top: -5px;}
              
          </style>

          主要是添加了一點縮進和間距,讓結果看起來更舒服一點,現(xiàn)在自動生成的 html 文件部分如下

          最后只需要將上述 Python 代碼封裝,然后在主函數(shù)運行結束后自動將相關參數(shù)進行傳遞,即可全程自動化生成 html 報告!

          當然本文介紹的 Jinja2 操作只是其簡單的一個應用,更多的用法與功能感興趣的讀者可以自己查閱官方文檔。


          ------------------- End -------------------

          往期精彩文章推薦:

          歡迎大家點贊,留言,轉發(fā),轉載,感謝大家的相伴與支持

          想加入Python學習群請在后臺回復【入群

          萬水千山總是情,點個【在看】行不行

          /今日留言主題/

          隨便說一兩句吧~~

          瀏覽 67
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲天堂美女 | 精品人妻无码一区二区三区竹菊影视 | 成人无码免费看 | 一区二区无码在线播放入口 | 大香蕉在线视频99 |