ShamilS
ShamilS

Reputation: 1594

pandas DataFrame .style.format is not working

import pandas as pd 
import numpy as np  

data = [['benzine', 1], ['benzine', 0], 
        ['diesel', 1], ['diesel', 0], ['diesel', 1],
        ['electro', 1], ['electro', 0], ['electro', 1],['electro', 1]]
df = pd.DataFrame(data, columns = ['engine_type', 'rented']) 

pt = df.pivot_table(index=['engine_type'], values= ['rented'], aggfunc=[np.mean])
pt.set_axis(['percent_on_rent'], axis = 'columns', inplace = True)
pt.style.format({'percent_on_rent': '{:.0%}'})
  
print(pt)

Current output:

             percent_on_rent
engine_type
benzine             0.500000
diesel              0.666667
electro             0.750000

Expected output:

             percent_on_rent
engine_type
benzine             50%
diesel              67%
electro             75$

NB: The following code

print(pt.to_string(float_format=lambda x: '{:.0%}'.format(x)))

works but I'd like to use .style.format(... to format several columns using different formatting styles as well as to set output table columns' (wrapped) captions.

[UPDATE]

Added:

print(pd.versions())

Result:

INSTALLED VERSIONS
------------------
commit           : None
python           : 3.8.3.final.0
python-bits      : 64
OS               : Windows
OS-release       : 10
machine          : AMD64
processor        : AMD64 Family 23 Model 24 Stepping 1, AuthenticAMD
byteorder        : little
LC_ALL           : None
LANG             : None
LOCALE           : English_United States.1252

pandas           : 1.0.5
numpy            : 1.19.1
pytz             : 2020.1
dateutil         : 2.8.1
pip              : 20.2.2
setuptools       : 41.2.0
Cython           : None
pytest           : None
hypothesis       : None
sphinx           : None
blosc            : None
feather          : None
xlsxwriter       : None
lxml.etree       : None
html5lib         : None
pymysql          : None
psycopg2         : None
jinja2           : 2.11.2
IPython          : 7.17.0
pandas_datareader: None
bs4              : None
bottleneck       : None
fastparquet      : None
gcsfs            : None
lxml.etree       : None
matplotlib       : 3.3.0
numexpr          : None
odfpy            : None
openpyxl         : None
pandas_gbq       : None
pyarrow          : None
pytables         : None
pytest           : None
pyxlsb           : None
s3fs             : None
scipy            : None
sqlalchemy       : None
tables           : None
tabulate         : None
xarray           : None
xlrd             : 1.2.0
xlwt             : None
xlsxwriter       : None
numba            : None
None

Upvotes: 3

Views: 11833

Answers (1)

ShamilS
ShamilS

Reputation: 1594

I have to admit that my question and its title were incorrectly set and I have to close this topic:

pt.style.format({'percent_on_rent': '{:.0%}'})

code line in my code snippet returns pandas Styler object instance linked to its parent pandas DataFrame object instance. AFAIU when Jupiter Notebook code cell with such a code is run then Jupiter Notebook captures pandas Styler object instance and immediately formats it for output under the running cell while

print(pt)

prints pandas DataFrame object instance and how this object instance string(?) representation is obtained by the print(...) Python method and sent to standard(?) output and this standard output captured by Jupiter Notebook and rendered under the cell where the code is running can be probably found only in the Jupiter Notebook sources. Writing and running in a Jupiter Notebook cell the following code:

my_styler = pt.style.format({'percent_on_rent': '{:.0%}'})
my_styler

would be equivalent to just

pt.style.format({'percent_on_rent': '{:.0%}'})

while

my_styler = pt.style.format({'percent_on_rent': '{:.0%}'})
print(my_styler)

would output

<pandas.io.formats.style.Styler object at 0x...>

Here is a link on a topic of using pandas Styler object in Jupiter Notebook. More information could be googled.

Please correct me if I'm still wrong in this explanation.

Thanks!

[Update]

Here is a sample code, which demonstrates how to return pandas Styler object instance from Python methods and then output them in Jupiter Notebook using display(...) method:

import numpy as np
import pandas as pd

def rc1():
    return np.random.choice(['benzine', 'diesel', 'electro'])

def rc2():
    return 1 if np.random.choice([True, False]) else 0

def test_pandas_styler(caption):
    # fill list
    data = []
    for i in range(21): data.append([rc1(), rc2()])
       
    # make data frame
    df = pd.DataFrame(data, columns = ['engine_type', 'rented']) 
    
    # make pivot table
    pt = df.pivot_table(index=['engine_type'], values= ['rented'], aggfunc=[np.mean]).reset_index()
    pt.set_axis(['engine type', 'percent on rent'], axis = 'columns', inplace = True)
    
    # style pivot table
    st = pt.style.format({'percent on rent': '{:.0%}'}).hide_index()    
    st.set_table_styles([
           dict(selector="th", props=[('color', 'darkblue'), 
                                      ('vertical-align', 'top')]),
           dict(selector="th:first-child", props=[('max-width', '70px'), ('text-align', 'left')]),
           dict(selector="th:last-child", props=[('max-width', '50px')]),
           dict(selector="td:first-child", props=[('text-align', 'left')])
            ])    
    st.caption = caption
    
    return st

for f in [test_pandas_styler('Test {}'.format(i)) for i in range(1,4)]:
    display(f)

Test output in Jupiter Notebook

Upvotes: 2

Related Questions