kjo
kjo

Reputation: 35311

How to customize headers and column widths of DataFrame display?

As a rule, I like to use long, descriptive column names (e.g. estimated_background_signal rather than just bg) for DataFrame objects. The one downside of this preference is that the DataFrame's display form has several columns that are much wider than their values require. For example:

In [10]: data.head()
     barcode estimated_background_signal inhibitor_code inhibitor_concentration
0  R00577279                         133            IRB                   0.001
1  R00577279                         189            SNZ                   0.001
2  R00577279                         101            CMY                   0.001
3  R00577279                         112            BRC                   0.001
4  R00577279                         244            ISB                   0.001

It would be nice if the display were narrower. Disregarding the headers, the narrowest display would be:

0 R00577279 113 IRB 0.001
1 R00577279 189 SNZ 0.001
2 R00577279 101 CMY 0.001
3 R00577279 112 BRC 0.001
4 R00577279 244 ISB 0.001

...but eliminating the headers altogether is not an entirely satisfactory solution. A better one would be to make the display wide enough to allow for some headers, possibly taking up several lines:

    barcode estim inhib inhib
            ated_ itor_ itor_
            backg code  conce
0 R00577279   113   IRB 0.001
1 R00577279   189   SNZ 0.001
2 R00577279   101   CMY 0.001
3 R00577279   112   BRC 0.001
4 R00577279   244   ISB 0.001

It's probably obvious that no single convention would be suitable for all situations, but, in any case, does pandas offer any way to customize the headers and column widths of a DataFrame's display form?

Upvotes: 8

Views: 2368

Answers (2)

Michael B
Michael B

Reputation: 578

There is obviously pd.set_option display settings you can utilize. If you're looking for a pandas specific answer that doesn't involve changing notebook display settings, consider the below.

df = pd.DataFrame(np.random.randn(10, 2), 
    columns=['Very Long Column Title ' + str(i) for i in range(2)])
df.style.set_table_styles([dict(selector="th",props=[('max-width', '50px')])])

Upvotes: 1

JohnE
JohnE

Reputation: 30424

This is a bit of a hack that uses the multi-index feature of pandas in a non-standard way, although I don't see any significant problems with doing that. Of course, there is some increased complexity from using a multi-index rather than a simple index.

cols = df.columns
lencols = [ int(len(c)/2) for c in cols ]

df.columns = pd.MultiIndex.from_tuples( 
                 tuple( ( c[:ln], c[ln:] ) for c, ln in zip(cols, lencols) ) )

Results:

         bar  estimated_bac inhibit  inhibitor_c
        code kground_signal or_code oncentration
0  R00577279            133     IRB        0.001
1  R00577279            189     SNZ        0.001
2  R00577279            101     CMY        0.001
3  R00577279            112     BRC        0.001
4  R00577279            244     ISB        0.001

You could also consider creating a dictionary to convert between long & short names as needed:

Upvotes: 1

Related Questions