Reputation: 47
I went to apply a style.format to one of my columns in the df (to add commas), but after calling df second time –– it seems that the style.format is not permanent? When I do assign the style.format to a variable and then call it, it does work. BUT calling df.head(5) gives me AttributeError: 'Styler' object has no attribute 'head'
import pandas as pd
pd.set_option('display.max_rows', 10)
df = pd.read_excel('./resources/mycopy-copy.xlsx')
df <---#truncates here
df.style.format({'Number of Doses Procured': '{:,}'}) #or df = df.style.format({'Number of Doses Procured': '{:,}'})
df <---#spits out all 500 rows
Upvotes: 4
Views: 4519
Reputation: 26221
The short answer is: no, there is no way to "apply a style permanently to a DataFrame
".
Styling is typically the last step before rendering (as HTML), although it can be composed by chaining.
The result of df.style.anyfunction()
is a Style
object. As such, it doesn't have the methods of DataFrame
, in particular as per your question, .head()
:
>>> type(df.style.format('${:,.2f}'))
pandas.io.formats.style.Styler
The DataFrame
doesn't know anything about any Styler
. Instead, it is the Styler
that has a reference to the DataFrame
it was originally used for.
You can take the style itself and apply it to another DataFrame
(with Styler.use()
and Styler.export()
, see below). However, regrettably, that doesn't seem to include .format()
definitions (at least in pandas=1.2.1
).
It's really too bad, because otherwise, it makes it quite easy to reuse a style for another DF (or df.head()
per your example):
def neg_red(x):
return f"color: {'red' if x < 0 else 'black'}"
df = pd.DataFrame(np.random.uniform(-4, 5, (5, 3)) * 1e4)
s = df.style.format('${:,.2f}').applymap(neg_red).highlight_max()
s
Observe that: assert vars(s)['data'] is df
. So as I said above, the Styler
object has a reference (data
) to the DataFrame
it was used on initially (so that, when it is asked to render, it knows what data to render).
Now, you can use the Styler
object and apply it to another DataFrame
(here: df.head(3)
):
df.head(3).style.use(s.export())
As you can see, all the styling functions have been carried over, except for the formatting! I would imagine this is a bug or an oversight.
Upvotes: 3