简体   繁体   中英

Wrapping column names in Python Pandas DataFrame or Jupyter Notebooks

I have long titles for some of my columns in my data frame, and I would like the ability to wrap the text. I know that this functionality is built into pandas, as I do:

pd.DataFrame(np.random.randn(2, 10), 
    columns=['Very Long Column Title ' + str(i) for i in range(10)])

DataFrame with wrapped column names

But if I have fewer columns, the titles will not wrap:

pd.DataFrame(np.random.randn(10, 2), 
    columns=['Very Long Column Title ' + str(i) for i in range(2)])

DataFrame does not wrap column names

I have also tried to manually insert a newline:

import pandas as pd    
pd.DataFrame(np.random.randn(10, 2), 
    columns=['Very Long \n Column Title ' + str(i) for i in range(2)])

But that gives the same output as above.

I've found similar for answers on this topic:

I am working in a Jupyter notebook, but would prefer a pandas-based solution, if possible.

Jupyter notebooks inherit their display properties from a number of sources. There is no property in pandas that restricts the width of the column headers because pandas is not what causes the text to wrap, it is actually the rendered HTML.

You can overwrite the default Jupyter Notebook styles to restrict the maximum width of the table headers using:

from IPython.core.display import HTML
HTML("<style>.rendered_html th {max-width: 120px;}</style>")

Run this code once at the top of your notebook to set the max column width of html table headers to 120 pixels.

Here is an answer that does not involve changing the IPython properties:

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')])])

Alternatively, you could use the package textwrap :

import textwrap

cols = ['Very Long Column Title ' + str(i) for i in range(2)]

# Split wide columns, you can then join these with any delimiter you'd like
cols = [textwrap.wrap(x, width=20) for x in cols]

# print(cols)
# [['Very Long Column', 'Title 0'], ['Very Long Column', 'Title 1']]

You can "hack in" the correct behavior by inserting spaces into column headings with:

def colfix(df, L=5): return df.rename(columns=lambda x: ' '.join(x.replace('_', ' ')[i:i+L] for i in range(0,len(x),L)) if df[x].dtype in ['float64','int64'] else x )

colfix(your_df)

See my answer to a similar question https://stackoverflow.com/a/45078833/6903458

A version of @AndreyF's answer that works regardless of whether you are using Jupyter. The routine uses the Pandas styler to render the dataframe as HTML. To view the table then, you must save the HTML to file and open it in a browser. Notice that the styler is caught explicitly as a variable.

df = pd.DataFrame(np.random.randn(10, 2), 
    columns=['Very Long Column Title ' + str(i) for i in range(2)])
styler = df.style.set_table_styles([dict(selector="th",props=[('max-width', '50px')])])
with open("/tmp/testStyle.html",'w') as f: f.write(styler.render())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM