When I run
import pandas as pd
from IPython.display import display
df = pd.DataFrame('a',index=pd.MultiIndex.from_product([[0,1]]*3),columns=['A'])
display(df)
display(df.style.apply(lambda x: ['']*len(x),axis=1))
in Jupyter, I get the following displays (unfortunately I cannot upload screenshots)
0 0 0 a
    1 a
  1 0 a
    1 a
1 0 0 a
    1 a
  1 0 a
    1 a
-
    0 a
  0  
    1 a
0
    0 a
  1  
    1 a
    0 a
  0  
    1 a
1
    0 a
  1  
    1 a
1: How do I prevent that change?
2: Since I actually don't dislike the second format completely: How can I fix the backgrounds in the multiindex, so that the boundaries of the groups in each multiindex level become visually clear?
(PS: In my actual code, the lambda returns 'background: green' for some rows)
There is a bit of relevant discussion on GitHub here and here regarding the default vertical-alignment CSS attribute that should be applied to th's; I think these CSS styles should give you a good starting point:
s=df.style.set_table_styles([
    {'selector': 'th',
    'props': [
        ('border-style', 'solid'),
        ('border-color', 'Red'),
        ('vertical-align','top')
    ]
    }]
)
HTML(s.render())
This would top-align the MultiIndices, and give them a red border.
Update
I don't know how you're evaluating your style/conditions, but if you had some 'b's in your DF (e.g. df.loc[0,0,1]='b', df.loc[1,0,1]='b') then you could define a styling function like:
def color_b_green(value):
  if value == 'b':
    color = 'blue'
  else:
    color = 'black'
  return 'color: %s' % color
and finally chain everything together (cleaned up here) like:
styles=[
    {'selector': 'th',
    'props': [
        ('border-style', 'solid'),
        ('border-color', 'Red'),
        ('vertical-align','top')
    ]
    }]
(df.style
    .apply(lambda x: ['']*len(x),axis=1)
    .applymap(color_b_green)
    .set_table_styles(styles))
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