Home > Net >  Truncate all values in dataframe
Truncate all values in dataframe

Time:12-31

I have a pandas dataframe with the first column being dates and then lots of adjusted stock prices (some of which have 16 decimals). I would like to truncate all the dataframe values to 8 decimals so I tried the following:

df = df.set_index("Day").pipe(lambda x: math.trunc(100000000 * x) / 100000000).reset_index()

But I get the following error:

type DataFrame doesn't define __trunc__ method

CodePudding user response:

Use numpy.trunc for a vectorial solution:

n = 10**8
out = np.trunc(df.set_index("Day").mul(n)).div(n).reset_index()

CodePudding user response:

Have you tried formatting?

dec = [1.2736,9.3745,5.412783,8.25389]
to_3dp = lambda x: '%.3f'%(x)
rounded = [to_3dp(i) for i in dec]
print(rounded) # [1.273, 9.374, 5.412, 8.253]

So in your case:

df['column'] = df['column'].apply(lambda x: '%.8f'%(x))

If you want to round:

df['column'] = df['column'].apply(lambda x: round(x,8))

CodePudding user response:

IIUC, you are trying to apply the truncate-based lambda function on multiple columns at once. That's the reason for the error, try using applymap which applies your function on each cell independently. You have to first set your date column as index, leaving only the float columns in the dataframe. Try this -

f = lambda x: math.trunc(100000000 * x) / 100000000  #<-- your function
df.set_index("Day").applymap(f).reset_index()        #<-- applied on each cell

Since I don't have the sample dataset you are using, here is a working dummy example.

import math
import pandas as pd

#Dummy dataframe
df = pd.DataFrame(np.random.random((10,3)), 
                  columns = ['col1','col2','col3'])

f = lambda x: math.trunc(100 * x) / 100
df.applymap(f)
   col1  col2  col3
0  0.80  0.76  0.14
1  0.40  0.48  0.85
2  0.58  0.40  0.76
3  0.82  0.04  0.10
4  0.23  0.04  0.91
5  0.57  0.41  0.12
6  0.72  0.71  0.71
7  0.32  0.59  0.99
8  0.11  0.70  0.32
9  0.95  0.80  0.24

Another simpler solution is to just use df.set_index("Day").round(8) directly, if that works for you but that would be rounding your numbers to 8 digits instead of truncating.

  • Related