Search code examples
pythonformattingtabulate

Python Tabulate format only one float column


I'm using the tabulate module to print a fixed width file and I have one column that I need formatted in such a way that there are 19 places to the left of the decimal and 2 places to the right of the decimal.

import pandas as pd

from tabulate import tabulate

df = pd.DataFrame.from_dict({'A':['x','y','z'],
'B':[1,1.1,11.21],'C':[34.2334,81.1,11]})

df
Out[4]: 
   A      B        C
0  x   1.00  34.2334
1  y   1.10  81.1000
2  z  11.21  11.0000

df['C'] = df['C'].apply(lambda x: format(x,'0>22.2f'))

df
Out[6]: 
   A      B                       C
0  x   1.00  0000000000000000034.23
1  y   1.10  0000000000000000081.10
2  z  11.21  0000000000000000011.00

print(tabulate(df))
-  -  -----  -----
0  x   1     34.23
1  y   1.1   81.1
2  z  11.21  11
-  -  -----  -----

Is there any way I can preserve the formatting in column C without affecting the formatting in column B? I know I could use floatfmt = '0>22.2f' but I don't need column B to look that way just column C.

According to the tabulate documentation strings that look like decimals will be automatically converted to numeric. If I could suppress this then format my table before printing (as in the example above) that would solve it for me as well.


Solution

  • The documentation at GitHub is more up-to-date and it states that with floatfmt "every column may have different number formatting". Here is an example using your data:

    import pandas as pd
    from tabulate import tabulate
    
    df = pd.DataFrame.from_dict({'A':['x','yy','zzz'],
    'B':[1,1.1,11.21],'C':[34.2334,81.1,11]})
    
    print(tabulate(df, floatfmt=(None, None, '.2f', '0>22.2f',)))
    

    The result is:

    -  ---  -----  ----------------------
    0  x     1.00  0000000000000000034.23
    1  yy    1.10  0000000000000000081.10
    2  zzz  11.21  0000000000000000011.00
    -  ---  -----  ----------------------
    

    Additionally, as you suggested, you also have the option disable_numparse which disables the automatic convert from string to numeric. You can then format each field manually but this requires more coding. The option colalign may come handy in such a case, so that you can specify different column alignment for strings and numbers (which you would have converted to formatted strings, too).