Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pagination on pandas dataframe.to_html()

Tags:

python

pandas

I have a huge pandas dataframe I am converting to html table i.e. dataframe.to_html(), its about 1000 rows. Any easy way to use pagination so that I dont have to scroll the whole 1000 rows. Say, view the first 50 rows then click next to see subsequent 50 rows?

like image 649
DougKruger Avatar asked Aug 11 '16 10:08

DougKruger


People also ask

How do you get the nth row in Pandas?

To get the nth row in a Pandas DataFrame, we can use the iloc() method. For example, df. iloc[4] will return the 5th row because row numbers start from 0.

How do I count row numbers in Pandas?

You can use len(df. index) to find the number of rows in pandas DataFrame, df. index returns RangeIndex(start=0, stop=8, step=1) and use it on len() to get the count.

What does To_string do in Pandas?

The to_string() function is used to render a DataFrame to a console-friendly tabular output. Buffer to write to. The subset of columns to write. Writes all columns by default.

How do you use Iterrows in Pandas?

iterrows() function in Python. Pandas DataFrame. iterrows() is used to iterate over a pandas Data frame rows in the form of (index, series) pair. This function iterates over the data frame column, it will return a tuple with the column name and content in form of series.


1 Answers

The best solution I can think of involves a couple of external JS libraries: JQuery and its DataTables plugin. This will allow for much more than pagination, with very little effort.

Let's set up some HTML, JS and python:

from tempfile import NamedTemporaryFile
import webbrowser

base_html = """
<!doctype html>
<html><head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.css">
<script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.js"></script>
</head><body>%s<script type="text/javascript">$(document).ready(function(){$('table').DataTable({
    "pageLength": 50
});});</script>
</body></html>
"""

def df_html(df):
    """HTML table with pagination and other goodies"""
    df_html = df.to_html()
    return base_html % df_html

def df_window(df):
    """Open dataframe in browser window using a temporary file"""
    with NamedTemporaryFile(delete=False, suffix='.html') as f:
        f.write(df_html(df))
    webbrowser.open(f.name)

And now we can load a sample dataset to test it:

from sklearn.datasets import load_iris
import pandas as pd

iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

df_window(df)

The beautiful result: enter image description here

A few notes:

  • Notice the pageLength parameter in the base_html string. This is where I defined the default number of rows per page. You can find other optional parameters in the DataTable options page.
  • The df_window function was tested in a Jupyter Notebook, but should work in plain python as well.
  • You can skip df_window and simply write the returned value from df_html into an HTML file.

Edit: how to make this work with a remote session (e.g. Colab)

When working on a remote notebook, like in Colab or Kaggle the temporary file approach won't work, since the file is saved on the remote machine and not accessible by your browser. A workaround for that would be to download the constructed HTML and open it locally (adding to the previous code):

import base64
from IPython.core.display import display, HTML

my_html = df_html(df)
my_html_base64 = base64.b64encode(my_html.encode()).decode('utf-8')
display(HTML(f'<a download href="data:text/html;base64,{my_html_base64}" target="_blank">Download HTML</a>'))

This will result in a link containing the entire HTML encoded as a base64 string. Clicking it will download the HTML file and you can then open it directly and view the table.

like image 176
Shovalt Avatar answered Oct 19 '22 00:10

Shovalt