pandas 如何将熊猫数据框显示为数据表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48622486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to display a pandas dataframe as datatable?
提问by Cleb
I want to display a table - which is a pandas dataframe - as a DataTable. In the simplified example below, I read two numbers provided by a user, that determine the row and column number of the table. The number of elements of this table is then displayed correctly, however, the table does not appear.
我想显示一个表格——它是一个Pandas数据框——作为一个DataTable。在下面的简化示例中,我读取了用户提供的两个数字,它们决定了表格的行号和列号。该表的元素数量随后会正确显示,但是,该表不会出现。
The problem is, I think, that I pass the table in the wrong way. When I try
我认为问题是我以错误的方式传递了桌子。当我尝试
return jsonify(number_elements=a * b,
my_table=df)
I get the error
我收到错误
anaconda2/lib/python2.7/json/encoder.py", line 184, in default raise TypeError(repr(o) + " is not JSON serializable")
TypeError: 0 1 2 3 0 51 35 10 84 1 30 60 79 24 is not JSON serializable
anaconda2/lib/python2.7/json/encoder.py", line 184, in default raise TypeError(repr(o) + " is not JSON serializable")
类型错误:0 1 2 3 0 51 35 10 84 1 30 60 79 24 不是 JSON 可序列化的
if I use
如果我使用
return jsonify(number_elements=a * b,
my_table=df.to_json())
then there is no error but the table is still not displayed.
然后没有错误,但表格仍然没有显示。
How would I do this correctly?
我将如何正确地做到这一点?
My index.html
file looks like this:
我的index.html
文件看起来像这样:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"
rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css"
rel="stylesheet">
<script type=text/javascript>
$(function() {
$('a#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('input[name="a"]').val(),
b: $('input[name="b"]').val()
}, function(data) {
$("#elements").text(data.number_elements);
$("#a_nice_table").DataTable(data.my_table);
});
return false;
});
});
</script>
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" name="a" value="2">
<p>Number of columns</p>
<input type="text" size="5" name="b" value="4">
<p><a href="javascript:void();" id="calculate">get a pretty table</a></p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<span id="a_nice_table">Here should be a table</span>
</div>
</div>
</body>
</html>
And my file app.py
looks like this:
我的文件app.py
如下所示:
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
# Initialize the Flask application
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)))
return jsonify(number_elements=a * b,
my_table=df)
if __name__ == '__main__':
app.run(debug=True)
回答by Scratch'N'Purr
Here's my implementation. I did some optimizations such as moving your js files to the end of the HTML:
这是我的实现。我做了一些优化,比如将你的 js 文件移动到 HTML 的末尾:
index.html
索引.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" name="a" value="2">
<p>Number of columns</p>
<input type="text" size="5" name="b" value="4">
<p><a href="javascript:void();" id="calculate">get a pretty table</a></p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<table id="a_nice_table">Here should be a table</table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = null;
$('a#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('input[name="a"]').val(),
b: $('input[name="b"]').val()
}, function(data) {
$("#elements").text(data.number_elements);
if (table !== null) {
table.destroy();
table = null;
$("#a_nice_table").empty();
}
table = $("#a_nice_table").DataTable({
data: data.my_table,
columns: data.columns
});
});
return false;
});
});
</script>
</body>
</html>
app.py
应用程序
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json
# Initialize the Flask application
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)))
return jsonify(number_elements=a * b,
my_table=json.loads(df.to_json(orient="split"))["data"],
columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])
if __name__ == '__main__':
app.run(debug=True)
What I modified:
我修改的内容:
- Added the js file to render the DataTable.
- Moved the js files down to the bottom of the HTML.
- Added a check in the js to destroy and clear columns when refreshing the data with new data.
- Used the
to_json
method with orient ofsplit
to generate the json data for DataTables. - Also had to add a
columns
json string for DataTables to consume, which is dynamically set after usingto_json
- 添加了 js 文件来呈现 DataTable。
- 将 js 文件移到 HTML 的底部。
- 在 js 中添加了一个检查以在使用新数据刷新数据时销毁和清除列。
- 使用
to_json
orient of的方法split
为DataTables生成json数据。 - 还得添加一个
columns
json字符串供DataTables消费,使用后动态设置to_json
Here's how to use panda's to_html
for generating the table:
以下是使用Pandasto_html
生成表格的方法:
index.html
索引.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" name="a" value="2">
<p>Number of columns</p>
<input type="text" size="5" name="b" value="4">
<p><a href="javascript:void();" id="calculate">get a pretty table</a></p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<div id="mytablediv">Here should be a table</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = null;
$('a#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('input[name="a"]').val(),
b: $('input[name="b"]').val()
}, function(data) {
$("#elements").text(data.number_elements);
if (table !== null) {
table.destroy();
table = null;
$("#a_nice_table").empty();
}
$("#mytablediv").html(data.my_table);
table = $("#a_nice_table").DataTable();
});
return false;
});
});
</script>
</body>
</html>
app.py
应用程序
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
# Initialize the Flask application
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index2.html')
@app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)))
return jsonify(number_elements=a * b,
my_table=df.to_html(classes='table table-striped" id = "a_nice_table',
index=False, border=0))
if __name__ == '__main__':
app.run(debug=True)
Differences from former implementation:
与之前实现的区别:
- In the HTML, I had to add a parent div in order to hold the generated HTML table. In this case, I called it
mytablediv
. - In the HTML on the JS side, I have to basically modify the HTML content of the
mytablediv
after I generate my data. This HTML content comes from theto_html
output. - In the HTML on the JS side, I didn't have to pass anymore data into the
DataTable
function because that would be handled with HTML code. - In
app.py
, I had to use a hackey method for pandas to generate an HTML ID tag. The ID tag lets JS know what element to modify. I used the solution from here. - In
app.py
, because I'm now generating HTML, I have to also explicitly specify other table style options likeborder=0
andindex=False
to mimic the former implementation.
- 在 HTML 中,我必须添加一个父 div 以保存生成的 HTML 表。在这种情况下,我称之为
mytablediv
。 - 在JS端的HTML中,我基本上要修改
mytablediv
我生成数据后的HTML内容。此 HTML 内容来自to_html
输出。 - 在 JS 端的 HTML 中,我不必再将数据传递到
DataTable
函数中,因为这将使用 HTML 代码进行处理。 - 在 中
app.py
,我不得不对 Pandas 使用 hackey 方法来生成 HTML ID 标签。ID 标签让 JS 知道要修改什么元素。我使用了这里的解决方案。 - 在 中
app.py
,因为我现在正在生成 HTML,所以我还必须明确指定其他表格样式选项,例如border=0
和index=False
模仿以前的实现。
回答by Arnaud
Shouldn't you generate an html
table first ? Taking advantage of the pandas.DataFrame.to_html()
function ? Indeed, the documentation of DataTablesshow an example using an html table.
你不应该先生成一个html
表吗?利用pandas.DataFrame.to_html()
功能 ? 事实上,DataTables的文档展示了一个使用 html 表格的例子。