The accepted answer suggests to modify the raw data for presentation purposes, something you generally do not want. Imagine you need to make further analyses with these columns and you need the precision you lost with rounding.
You can modify the formatting of individual columns in data frames, in your case:
output = df.to_string(formatters={
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format
})
print(output)
For your information '{:,.2%}'.format(0.214) yields 21.40%, so no need for multiplying by 100.
You don't have a nice HTML table anymore but a text representation. If you need to stay with HTML use the to_html function instead.
from IPython.core.display import display, HTML
output = df.to_html(formatters={
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format
})
display(HTML(output))
Update
As of pandas 0.17.1, life got easier and we can get a beautiful html table right away:
df.style.format({
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format,
})
Answer from linqu on Stack OverflowThe accepted answer suggests to modify the raw data for presentation purposes, something you generally do not want. Imagine you need to make further analyses with these columns and you need the precision you lost with rounding.
You can modify the formatting of individual columns in data frames, in your case:
output = df.to_string(formatters={
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format
})
print(output)
For your information '{:,.2%}'.format(0.214) yields 21.40%, so no need for multiplying by 100.
You don't have a nice HTML table anymore but a text representation. If you need to stay with HTML use the to_html function instead.
from IPython.core.display import display, HTML
output = df.to_html(formatters={
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format
})
display(HTML(output))
Update
As of pandas 0.17.1, life got easier and we can get a beautiful html table right away:
df.style.format({
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format,
})
You could also set the default format for float :
pd.options.display.float_format = '{:.2%}'.format
Use '{:.2%}' instead of '{:.2f}%' - The former converts 0.41 to 41.00% (correctly), the latter to 0.41% (incorrectly)
python - pandas convert columns to percentages of the totals - Stack Overflow
pandas - format number (based on calculation) as a percentage to two decimal places using python - Stack Overflow
Formatting floating point values as percent in column_config
Converting pandas column to percentage
Showing us what CSV_DAX['EL4F'] and date_DAX looks like would help us a lot. What you have seems okay with the limited information you gave us.
Videos
Hi - how to convert decimal numbers such as 0.0555 to percent to display percentage sign as 5.55% ?
I tried below I have two problems:
-
some values have 1 and some two decimals in my output excel file.
-
when I export to excel it's string not value. When I convert to value manually in excel I get two see two decimal places.
How to solve this in pandas, to display two decimal places with percent sign and to be value. Keep in mind that excel file will feed client database and can't be text or string.
df["Value"]= df["Value"].astype(float)
df["Value"]=df["Value"]*100
df["Value"]=df["Value"].round(2)
df["Value"]=df["Value"].astype(str) + "%"
You can do this using basic pandas operators .div and .sum, using the axis argument to make sure the calculations happen the way you want:
cols = ['<80%', '80-90', '>90']
df[cols] = df[cols].div(df[cols].sum(axis=1), axis=0).multiply(100)
- Calculate the sum of each column (
df[cols].sum(axis=1).axis=1makes the summation occur across the rows, rather than down the columns. - Divide the dataframe by the resulting series (
df[cols].div(df[cols].sum(axis=1), axis=0).axis=0makes the division happen across the columns. - To finish, multiply the results by
100so they are percentages between 0 and 100 instead of proportions between 0 and 1 (or you can skip this step and store them as proportions).
df/df.sum()
If you want to divide the sum of rows, transpose it first.
You forgot to make a string:
format_percent = '{:.2f}'.format(percent_val)
# ^ ^
Also, if you want a percent, you'll need to multiply by 100, and if you're on Python 2 (I can't tell), you'll either need to use floats or from __future__ import division.
If you want to round the number to two decimal places, rather than creating formatted output, there's the round function:
rounded = round(percent_val, 2)
Then your output will be a float instead of a string, and you can keep doing math with it.
You can plug the display format into pandas' display options:
In [11]: df = pd.DataFrame(np.random.randn(2, 2))
In [12]: df
Out[12]:
0 1
0 1.058814 -0.011675
1 -0.002627 -0.152505
In [13]: pd.options.display.float_format = '{:.2f}'.format
In [14]: df
Out[14]:
0 1
0 1.06 -0.01
1 -0.00 -0.15
See more about python's string formatting here.
Note: the numbers themselves are unaffected (they haven't been rounded):
In [15]: df.iloc[0, 0]
Out[15]: 1.058814403984879
Hey folks, I downloaded a CSV file from the internet and I wanted to convert one column into percentage with the first value in the column being 100 %. My approach looks as follows:
In the first step I fetch the first value of the column and make it a variable:
DAX_first=CSV_DAX['EL4F'].iloc[0]
In the second step I try to turn everything into percentages by the following:
plt.plot(date_DAX, CSV_DAX['EL4F']/DAX_first*100)
data_DAX contains the values for the X-axis obviously. The plot that I obtain doens't start at 100% but instead at around 60 %. Probably there's a blatant mistake somewhere but I don't see it at the moment. Can anyone spot the mistake?
First convert column to floats by astype:
df['C'] = df['C'].astype(float).map(lambda n: '{:.2%}'.format(n))
Also solution should be simplify:
df['C'] = df['C'].astype(float).map("{:.2%}".format)
EDIT:
Problem is some non numeric values in column.
Replace non numeric to 0:
print (df)
C
0 0.9977
1 0.1234
2 Covered fraction
df['C'] = pd.to_numeric(df['C'], errors='coerce').fillna(0).map("{:.2%}".format)
print (df)
C
0 99.77%
1 12.34%
2 0.00%
Or remove rows with these values:
df['C'] = pd.to_numeric(df['C'], errors='coerce')
df = df.dropna(subset=['C'])
df['C'] = df['C'].astype(float).map("{:.2%}".format)
print (df)
C
0 99.77%
1 12.34%
You can also use df.style:
df.style.format({'C': '{:.2%}'})
If your series data type is not an issue and want to use it as string try:
df['C'] = df.C.apply(lambda x: f"{x[:x.find('.')+3]}%")
df
C
0 0.99%
1 0.12%
2 1.00%
OR if using python <3.6:
df['C'] = df.C.apply(lambda x: x[:x.find('.')+3]+'%')
Using Jezrael's idea convert to numeric column and invalid strings as 0:
df['C'] = pd.to_numeric(df['C'], errors='coerce').fillna(0)
df.style.format({'C': '{:.2%}'})
Use pandas' broadcasting operations:
df.rating = (df.rating * 100).astype(str) + '%'
df
name rating
0 Johnny 100.0%
1 Brad 90.0%
Alternatively, using df.mul and df.add:
df.rating = df.rating.mul(100).astype(str).add('%')
df
name rating
0 Johnny 100.0%
1 Brad 90.0%
df['rating'] = df['rating'].mul(100).astype(int).astype(str).add('%')
print(df)
Output:
name rating
0 Johnny 100%
1 Brad 90%