Conditional Numerical Formatting for Datatable (Some Rows Not Others)

Is there a way to apply conditional numerical formatting to a datatable so that it affects some rows but not others?

I have a datatable created from a pandas dataframe where the first 20 or so rows are money, but the last 10 rows are integers. I can easily format the entire table as money with:

columns = [{'name': i, 'id': i, 'type':'numeric','format': FormatTemplate.money(2)} for i in table.columns]

But I really only want it to format the first 20 rows as “money,” leaving the last 10 or so rows as plain numbers.

I know I can fudge this by changing the dtypes of the rows that I don’t want formatted (e.g., if I change the last 10 rows to strings, those rows won’t be formatted by FormatTemplate.money(), but changing the dtype of some rows impacts the dtype of the entire column (because of the mixed dtypes). I’d prefer to avoid this

I was hoping there was a better way to accomplish this using conditional formatting. Any suggestions?

Try to apply conditional filling of column list. Maybe this will work for you. For example:

columns = [{'name': i, 'id': i, 'type':'numeric','format': FormatTemplate.money(2)} if n < 20 else {'name': i, 'id': i} for n, i in enumerate(table.columns)]

This is still formatting the entire column tho. As I understand it, OP is looking to exclude ROWS from the formatting template.

I too am seeking a solution for this, but am coming up short.

Hi, I was the original poster and I never did find an elegant way to accomplish this. What I ended up doing was running each column through a for loop:

for x in range(1,len(df.columns)):
    if df.iat[3,x]:
        df.iat[3,x] = '{:.0%}'.format(df.iat[3,x])
    if df.iat[9,x]:
        df.iat[9,x] = '{:,.2f}'.format(df.iat[9,x])
    if df.iat[12,x]:
        df.iat[12,x] = '{:,.2f}'.format(df.iat[12,x])

Because we are performing operations on rows and not columns (and thus cannot use vectorized operations), we have to use iat instead of iloc. ‘iat’ allows us to access scalar (single) elements in format:

df.iat[row_idx,col_idx]

Obviously not ideal because you need to know which rows you want to format beforehand (although mine are hardcoded, you can probably also determine the row locations dynamically and then loop through an array for row_idx). There may also be a way to use a pandas Styler object, but I couldn’t figure out how to easily get that to work in dash.

I appreciate this, it does help me!

As far as i undarstand you are formatting DataFrame here but not DashTable. After such formating you got strs instead of floats and it can give some problems while sorting DataTable.
I see like DashTable doesn’t have a way to format each cell individualy. Dash AG Grid can be more flexible in that terms.

1 Like

You are correct. Adding formatting to the dataframe can screw up pandas functionality. So it needs to be the last thing that you do before building the table. Dash AG Grid is on my Todo list!