Insert a link inside a Pandas table
Question:
I’d like to insert a link (to a web page) inside a Pandas table, so when it is displayed in an IPython notebook, I could press the link.
I tried the following:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame(range(5), columns=['a'])
In [3]: df['b'] = df['a'].apply(lambda x: 'http://example.com/{0}'.format(x))
In [4]: df
Out[4]:
a b
0 0 http://example.com/0
1 1 http://example.com/1
2 2 http://example.com/2
3 3 http://example.com/3
4 4 http://example.com/4
But the URL is just displayed as text.
I also tried using an IPython HTML object:
In [5]: from IPython.display import HTML
In [6]: df['b'] = df['a'].apply(lambda x:HTML('http://example.com/{0}'.format(x)))
In [7]: df
Out[7]:
a b
0 0 <IPython.core.display.HTML object at 0x0481E530>
1 1 <IPython.core.display.HTML object at 0x0481E770>
2 2 <IPython.core.display.HTML object at 0x0481E7B0>
3 3 <IPython.core.display.HTML object at 0x0481E810>
4 4 <IPython.core.display.HTML object at 0x0481EA70>
But it will only display the repr of the object.
Any other ideas?
alko got the right answer. I just wanted to add that the cell width is limited by default, and long HTML code will be truncated, i.e.:
<a href="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0">xxx</a>
will become this:
<a href="aaaaaaaaaaaaaaaaaaaaaa...
and won’t be displayed correctly. (Even though the text xxx is short and can fit in the cell.)
I’ve bypassed it by setting:
pd.set_printoptions(max_colwidth=-1)
Answers:
I suppose you have to represent whole Pandas object as an HTML object, that is
In [1]: from IPython.display import HTML
In [2]: df = pd.DataFrame(list(range(5)), columns=['a'])
In [3]: df['a'] = df['a'].apply(lambda x: '<a href="http://example.com/{0}">link</a>'.format(x))
In [4]: HTML(df.to_html(escape=False))
Sorry, now I don’t have IPython at hand, and can’t check whether the output is correct.
Since version 24, Pandas has a native way to deal with links: pandas.DataFrame.to_html
This works:
df["col"] = df["col"].apply( # insert links
lambda x: "<a href='https://link{}'>{}</a>".format(
re.findall("pattern", x)[0], x
)
)
df.to_html(
render_links=True,
escape=False,
)
If you want to avoid the issue of shortening the long urls you can also display the links with unique or standard values i.e.
df['Url'] = '<a href=' + df['Url'] + '><div>' + df['Name'] + '</div></a>'
df = df.to_html(escape=False)
# OR
df['Url'] = '<a href=' + df['Url'] + '><div>'Hello World'</div></a>'
df = df.to_html(escape=False)
Install pretty-html-table
from pretty_html_table import build_table
body = """
<html>
<head>
</head>
<body>
{0}
</body>
</html>
""".format(build_table(df, 'blue_light'))
You need not have to worry about the formatting and also of the website links in your DataFrame, the output will be with hyperlinks only.
I’d like to insert a link (to a web page) inside a Pandas table, so when it is displayed in an IPython notebook, I could press the link.
I tried the following:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame(range(5), columns=['a'])
In [3]: df['b'] = df['a'].apply(lambda x: 'http://example.com/{0}'.format(x))
In [4]: df
Out[4]:
a b
0 0 http://example.com/0
1 1 http://example.com/1
2 2 http://example.com/2
3 3 http://example.com/3
4 4 http://example.com/4
But the URL is just displayed as text.
I also tried using an IPython HTML object:
In [5]: from IPython.display import HTML
In [6]: df['b'] = df['a'].apply(lambda x:HTML('http://example.com/{0}'.format(x)))
In [7]: df
Out[7]:
a b
0 0 <IPython.core.display.HTML object at 0x0481E530>
1 1 <IPython.core.display.HTML object at 0x0481E770>
2 2 <IPython.core.display.HTML object at 0x0481E7B0>
3 3 <IPython.core.display.HTML object at 0x0481E810>
4 4 <IPython.core.display.HTML object at 0x0481EA70>
But it will only display the repr of the object.
Any other ideas?
alko got the right answer. I just wanted to add that the cell width is limited by default, and long HTML code will be truncated, i.e.:
<a href="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0">xxx</a>
will become this:
<a href="aaaaaaaaaaaaaaaaaaaaaa...
and won’t be displayed correctly. (Even though the text xxx is short and can fit in the cell.)
I’ve bypassed it by setting:
pd.set_printoptions(max_colwidth=-1)
I suppose you have to represent whole Pandas object as an HTML object, that is
In [1]: from IPython.display import HTML
In [2]: df = pd.DataFrame(list(range(5)), columns=['a'])
In [3]: df['a'] = df['a'].apply(lambda x: '<a href="http://example.com/{0}">link</a>'.format(x))
In [4]: HTML(df.to_html(escape=False))
Sorry, now I don’t have IPython at hand, and can’t check whether the output is correct.
Since version 24, Pandas has a native way to deal with links: pandas.DataFrame.to_html
This works:
df["col"] = df["col"].apply( # insert links
lambda x: "<a href='https://link{}'>{}</a>".format(
re.findall("pattern", x)[0], x
)
)
df.to_html(
render_links=True,
escape=False,
)
If you want to avoid the issue of shortening the long urls you can also display the links with unique or standard values i.e.
df['Url'] = '<a href=' + df['Url'] + '><div>' + df['Name'] + '</div></a>'
df = df.to_html(escape=False)
# OR
df['Url'] = '<a href=' + df['Url'] + '><div>'Hello World'</div></a>'
df = df.to_html(escape=False)
Install pretty-html-table
from pretty_html_table import build_table
body = """
<html>
<head>
</head>
<body>
{0}
</body>
</html>
""".format(build_table(df, 'blue_light'))
You need not have to worry about the formatting and also of the website links in your DataFrame, the output will be with hyperlinks only.