Can't adjust dataframes decimal places

I have a dataframe with integer and float columns like so:

And as you can see, some values in the Days_to_Sell column have no decimal places, while others have 4. In order to try and have some sorts of consistency, I want to use only 2 decimal places. In order to achieved that, I use the panda’s round function like so:

st.dataframe(df_display.round(2))

But got the same result.

Is there anyway I can change the number of decimal places besides using .round, that actually works with streamlit?

1 Like

Use pandas Styles. https://docs.streamlit.io/api.html?highlight=style#streamlit.dataframe

Hey @marciorpcoelho,

As @knorthover pointed out, you can pass pandas Styler to style your dataframe, most notably how to change the display of values.

The following works :

df = pd.DataFrame(
   np.random.randn(50, 20),
   columns=('col %d' % i for i in range(20))
)

st.dataframe(df.style.format("{:.2%}"))

2 Likes

Thank you for your help. From my original dataframe:

I tried to implement a style on the last three columns, like so:

df.style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.1f}'})

But notice how it didn’t make any change, aside from the 1.199.2 value:

So fater adjusting the style like:

df..style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.2f}'})

This is what I got:

Which is still far from my goal which is 1, 2 and 1 decimal place in Quantidade, PVP and Dias de Venda columns, respectively.

Does anyone know the reason for this apparent erratic behavior?

Hi @marciorpcoelho,

Can you try this sample code and let me know if it works for you?

import numpy as np
import pandas as pd

import streamlit as st

np.random.seed(24)
df = pd.DataFrame({"A": np.linspace(1, 5, 5)})
df = pd.concat([df, pd.DataFrame(np.random.randn(5, 4), columns=list("BCDE"))], axis=1)
df.iloc[0, 2] = np.nan

# Unstyled
st.table(df)

# Custom formatting
st.table(df.style.format({"E": "{:.2f}"}))

If that works fine, can you provide sample code so we can reproduce your issue on our end?

Thank you for your reply. Using your example, it worked as intended:

But when I applied to my case with:

st.table(df.style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.2f}'}))

This is the result I got:
´

The decimal place is still inconsistent throught the columns. Not to mention that I avoided using st.table, due to the lack of limit in the number of row’s output.

Hey @marciorpcoelho - could you provide sample code that demonstrates your issue, so we can help you track it down?

I had already shown some code I was using, but sure, here’s a full working example:

import streamlit as st
import pandas as pd

part_refs = ['AM85.45.2.545.505', 'AM85.45.2.545.506', 'AM85.45.2.547.501',
             'AM85.45.2.548.070', 'AM85.45.2.548.314', 'AM85.45.2.548.315',
             'AM85.45.2.593.502', 'AM85.45.2.593.784', 'AM85.45.2.593.789',
             'AM85.45.2.593.872']
quantities = [2.0, 2.0, 8.0, 1.0, 2.0, 1.0, 1.0, 3.0, 1.0, 2.0]
pvps = [98.5, 94.0, 134.0, 176.5, 187.5, 214.5, 304.0, 246.0, 177.95, 254.4]
days_to_sell = [7.0, 7.0, 1.75, 12.5, 7.0, 9.0, 8.0, 5.0, 14.0, 7.5]
df = pd.DataFrame({'Referência': part_refs, 'Quantidade': quantities, 'PVP': pvps, 'Dias de Venda': days_to_sell})

# Unstyled
st.dataframe(df)

# Styled
st.dataframe(df.style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.2f}'}))

Which produce the following results:

Thanks! It’s always useful to have a full test case, to ensure everyone’s looking at exactly the same data and code.

I’ve tracked down the cause of the issue and opened a bug here. The fix is potentially very simple but involves a bandwidth tradeoff - we’ll discuss it as a team and figure out the best way to get this taken care of! Thanks for helping us figure this out.

4 Likes

Ah ok, thanks for the info.
Just glad I could help in finding the bug!

Try with below:

st.write(df.style.format("{:.2}"))

Or

st.DataFrame(df.style.format("{:.2}"))

Thanks for the help but I had already tried this method for testing purposes. The problem is that I wanted to specify different decimal cases for each column.

Olá, Marcio
use “.set_precision(2)” no styler.

For those who see this issue in the future:

Just add .set_precision(2) to your styler

This solution seems to be more functional

Check this examples for a dataframe called ‘tabela’
st.dataframe(tabela.style.background_gradient(cmap=‘Greens’).set_precision(2),height=500)

1 Like

Thanks for your reply Andre_Holanda, but would your solution allow me to customize the number of decimal places per column instead of a applying a precision of 2 decimal places across all dataframe?