I am using df.to_excel()
to output data from a pandas dataframe to excel. To improve readability, I am using df.style.applymap()
to change the color of the cell based on the contents.
Imagine I have a dataframe that looks like:
df =
Account Revenue AccountAge
0 "Boeing" 5000 5.6
1 "Lockheed" -10000 1.2
2 "Airbus" 12000 0.6
3 "Northrop" -3000 8.4
Where account age represents how long I have had this account on my books. Perhaps I want to flag negative revenue cells as red. I can do:
def color_neg_revenue(val):
if val < 0:
color = 'red'
return "background-color: %s" % color
df = df.style.applymap(color_neg_revenue, subset=["Revenue"])
I can export this to excel, and the format looks great! But suppose I also want to flag new accounts in yellow, when I try:
def color_new_account(val):
if val < 3:
color = 'yellow'
return "background-color: %s" % color
df = df.style.applymap(color_new_account, subset=["AccountAge"])
I get:
AttributeError: 'Styler' object has no attribute 'style'
Why can I not use applymap()
on a dataframe that I have already used applymap()
on? How can I get around this?
What is the difference between map(), applymap() and apply() methods in pandas? – In padas, all these methods are used to perform either to modify the DataFrame or Series. map() is a method of Series, applymap() is a method of DataFrame, and apply() is defined in both DataFrame and Series.
applymap in more recent versions has been optimised for some operations. You will find applymap slightly faster than apply in some cases. My suggestion is to test them both and use whatever works better. map is optimised for elementwise mappings and transformation.
Series Map: We could also choose to map the function over each element within the Pandas Series. This is actually somewhat faster than Series Apply, but still relatively slow.
The problem is not with the function. In your first call you perform:
df = df.style.applymap(color_neg_revenue, subset=["Revenue"])
So now df
is no longer a DataFrame
, it is a Styler
. Such Styler
has of course no .style
attribute anymore. You thus better assign it to another variable, and chain on that one. Like:
s = df.style.applymap(color_neg_revenue, subset=["Revenue"])
# Look mom, no I have no .style
s = s.applymap(color_new_account, subset=["AccountAge"])
You thus can chain such applymap
calls when you use a Styler
, but such styler has no .style
attribute itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With