46
votes

I use pd.set_option("display.colheader_justify","right") to set the column header. But I can't find the option for data by pd.describe_option().

How to set the data within a dataframe display left or right alignment for each column? Or, is it possible to define a format template for the whole row data display?

8
I don't think this exists, by default data is right justified according to the header position there only exists options to format the header not the data as far as I can see - EdChum
are you looking to achieve this in the notebook or in general? - elyase
I don't think this exists (I know about some formatting stuff for pivots and Pandas Pretty Tables module), but AFAIK these won't do what you want. If all you need is to print the data, you can use to_string(justify-'left') - but this would apply it for all columns. It also seemed that this would work only if your column name is large enough to actually force the entries in the column to be justified. If the column name is small and the entry is large, it won't have any justification effect. - Sreyantha Chary
Most of these answers don't work on the console, for strings, apparently only in Jupyter Notebook (as of pandas 0.25), or for numeric fields. Please make sure to state which. - smci

8 Answers

21
votes

If you want to change the display in a Jupyter Notebook, you can use the Style feature.

# Test data
df = DataFrame({'text': ['foo', 'bar'],
                 'number': [1, 2]})

df.style.set_properties(**{'text-align': 'right'})

enter image description here

16
votes

The answer given by @Romain is great but I would like to summarize some comments:

# Test data
df = DataFrame({'text': ['foo', 'bar'],'number': [1, 2]})

dfStyler = df.style.set_properties(**{'text-align': 'left'})
dfStyler.set_table_styles([dict(selector='th', props=[('text-align', 'left')])])

will align all table text and the column headers as well.

4
votes

If you wanna align both text and header to the left for example you can use:

df.style.set_properties(**{'text-align': 'left'}).set_table_styles([ dict(selector='th', props=[('text-align', 'left')] ) ])

This first sets the text to the left and then the header.

4
votes

Instead of justifying all columns the same way, I had a need to justify some columns differently. Since there was no mention in this thread, I thought of reminding the presence of the subset option:

Styler.set_properties(subset=None, **kwargs)[source]

From the same example as the OP, one could left justify just the 'text' column:

df = pd.DataFrame({'text': ['foo', 'bar'],
             'number': [1, 2]})
dfStyler = df.style.set_properties(subset=['text'],**{'text-align': 'left'})
3
votes

I wrapped @Hagbard's answer in a function to use it whenever I wish to display a pandas dataframe consisting English text on a notebook cell:

from pandas import DataFrame


def left_align(df: DataFrame):
    left_aligned_df = df.style.set_properties(**{'text-align': 'left'})
    left_aligned_df = left_aligned_df.set_table_styles(
        [dict(selector='th', props=[('text-align', 'left')])]
    )
    return left_aligned_df

To show a dataframe, I simply write this:

left_align(df.head())

enter image description here

Caution: For large datasets, it prints all the rows and columns of df without any abstraction, so Jupyter crashes! That's why I use it with .head() or .tail() or some other limit.)

2
votes

you can control it by a new context:

with pd.option_context('display.colheader_justify','right'):
    ...
1
votes
pip3 install tabulate

from tabulate import tabulate
df = pd.DataFrame ({'Text': ['abcdef', 'x'], 'Value': [12.34, 4.2]})
print(tabulate(df, showindex=False, headers=df.columns))

Text      Value
------  -------
abcdef    12.34
x          4.2

This will automatically align pandas header and column data to good view format. Automatically align pandas dataframes columns data to left. Removes showing of the index in pandas dataframe. Puts ---- between the header and column data.

0
votes

In my situation, I have a class wrapper around my Pandas DataFrame. This allows me to left-justify the DataFrame's string output by customizing the wrapper's __str__() method.

Here's how I solved the problem for my application, based on Unutbu's answer to a similar question. The Pandas DataFrame is referenced by self.data:

def __str__(self):
    """
    Return the test stats report as a single string
    with left-justified columns.

    """
    # Columns containing boolean values need different format strings
    # to avoid 'ValueError: Invalid format specifier' exceptions.
    BOOL_COLUMNS = ['success',]

    formatters = {}
    for li in list(self.data.columns):
        if li in BOOL_COLUMNS:
            form = "{{!s:<5}}".format()
        else:
            max = self.data[li].str.len().max()
            form = "{{:<{}s}}".format(max)

        formatters[li] = functools.partial(str.format,form)

    return self.data.to_string(formatters=formatters, index=False)