How to set the pandas dataframe data left/right alignment?

PythonPandas

Python Problem Overview


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?

Python Solutions


Solution 1 - Python

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

Solution 2 - Python

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.

Solution 3 - Python

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.

Solution 4 - Python

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

Solution 5 - Python

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.

Solution 6 - Python

you can control it by a new context:

with pd.option_context('display.colheader_justify','right'):
    ...

Solution 7 - Python

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.)

Solution 8 - Python

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)

Solution 9 - Python

Since solutions using pandas.Styler don't work in console printing (at least for me), I came up with the following code using pandas 1.3.3 and an example dataframe, printing all string columns left aligned (w/o header):

    df = pd.DataFrame({'float': [0.123, 7],
                       'int': [3, 357676],
                       'str': ["hello world", "bye"],
                       'cat': pd.Series(["a", "bbb"], dtype="category"),
                       'bool': [True, False]
                       })

    formatters = {}
    for col in df.select_dtypes("object"):
        len_max = df[col].str.len().max()
        formatters[col] = lambda _: f"{_:<{len_max}s}"

    print(df.to_string(formatters=formatters))
       float     int          str  cat   bool
    0  0.123       3  hello world    a   True
    1  7.000  357676  bye          bbb  False

If you also want to align the header left, add justify='left'. For some reason the header is now one character too far to left for some columns, but not for all:

    print(df.to_string(formatters=formatters, justify="left"))
       float  int    str          cat   bool 
    0  0.123       3  hello world    a   True
    1  7.000  357676  bye          bbb  False

However applying this pattern to other dtypes fails (also for string columns). I have no idea why this occurs. Be aware that string conversion is added below via astype, also inside the f-string:

    formatters = {}
    for col in df.columns:
        len_max = df[col].astype(str).str.len().max()
        formatters[col] = lambda _: f"{_!s:<{len_max}s}"
        print(col, len_max)

    print(df.to_string(formatters=formatters))
      float    int          str    cat   bool
    0 0.123  3      hello world  a      True 
    1 7.0   357676        bye    bbb    False

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbigbugView Question on Stackoverflow
Solution 1 - PythonRomainView Answer on Stackoverflow
Solution 2 - PythonHagbardView Answer on Stackoverflow
Solution 3 - PythonShah VipulView Answer on Stackoverflow
Solution 4 - PythonHeelaraView Answer on Stackoverflow
Solution 5 - PythonFederico GentileView Answer on Stackoverflow
Solution 6 - PythonmozlingyuView Answer on Stackoverflow
Solution 7 - PythonShahrokh BahView Answer on Stackoverflow
Solution 8 - PythonJS.View Answer on Stackoverflow
Solution 9 - PythonascripterView Answer on Stackoverflow