こんにちは、データサイエンティストのたぬ(@tanuhack)です!
今回は、Flaskを使った簡単なWebアプリケーションで、PandasのDataFrameを最小のHTMLとjinja2テンプレートエンジンの変数を使って、Webページ上に表示させる方法を紹介します。
サーバーサイド側の処理によってDataFrameのサイズが動的に変化しても、レイアウトが崩れないように設計しているので、よかったら参考にしてみてください。
[aside]補足HTMLのテンプレートエンジンはjinja2を使用しています。jinja2の使い方があやしい人は過去記事にめっちゃ詳しくまとめたのであわせてどうぞ

app.py(Python)の設定
df-to-web/
├ app.py
├ templates/
│ └ index.html
└ static/
└ style.css
├ app.py
├ templates/
│ └ index.html
└ static/
└ style.css
サーバーサイドのDataFrameをクライアントサイドのHTMLに渡すには、『カラム名の1次元配列のリスト』と『インデックスを含まない全レコードの2次元配列のリスト』をそれぞれ変数に代入し、Flaskのrender_template
メソッドでそれぞれを引数にして渡します。
値 | 説明 |
---|---|
df.columns |
カラム名の1次元配列のリストを取得 |
df.values.tolist() |
インデックスを含まない全レコードの2次元配列のリストを取得 |
当記事では、機械学習の勉強で良く使用されるアヤメ(iris)のデータセットを変数dfに格納するものとして進めます。(※DataFrameの中身は何でも大丈夫です。)
from flask import Flask, render_template
import pandas as pd
app = Flask(__name__)
df = pd.read_csv('static/csv/iris.csv')
header = df.columns # DataFrameのカラム名の1次元配列のリスト
record = df.values.tolist() # DataFrameのインデックスを含まない全レコードの2次元配列のリスト
@app.route('/')
def index():
return render_template('index.html', header=header, record=record)
if __name__ == '__main__':
app.run()
index.html(HTML)の設定
df-to-web/
├ app.py
├ templates/
│ └ index.html
└ static/
└ style.css
├ app.py
├ templates/
│ └ index.html
└ static/
└ style.css
HTMLのtableタグとjinja2のforループを使って最小限のHTMLの記述だけで、DataFrameをブラウザ上に表示させます。
{% for i in header: %}
<th scope="col">{{ i }}</th>
{% endfor %}
{% for i in record: %}
<tr>
{% for j in i: %}
<td>{{ j }}</td>
{% endfor %}
</tr>
{% endfor %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>DataFrameをブラウザ上に表示させる</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<table>
<thead>
<tr>
{% for i in header: %}
<th scope="col">{{ i }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for i in record: %}
<tr>
{% for j in i: %}
<td>{{ j }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
style.css(CSS)の設定
df-to-web/
├ app.py
├ templates/
│ └ index.html
└ static/
└ style.css
├ app.py
├ templates/
│ └ index.html
└ static/
└ style.css
CSSに関しては、特に言うことはありません。HTML側のclass名にあわせて、適宜修正してください。
table {
margin-top: 1em;
margin-left: auto;
margin-right: auto;
border: none;
border-collapse: collapse;
border-spacing: 0;
color: black;
font-size: 12px;
table-layout: fixed;
text-align: right;
padding: 0.4em;
}
thead {
border-bottom: 1px solid black;
vertical-align: bottom;
}
tbody tr:nth-child(odd) {
background: #f5f5f5;
}
tr, th, td {
text-align: right;
vertical-align: middle;
padding: 0.5em 0.5em;
line-height: normal;
white-space: normal;
max-width: none;
border: none;
}
th {
font-weight: bold;
}