Округление записей в кадре Pandas DafaFrame

использование :

newdf3.pivot_table(rows=['Quradate'],aggfunc=np.mean)

что дает:

           Alabama_exp  Credit_exp  Inventory_exp   National_exp    Price_exp   Sales_exp
Quradate                        
2010-01-15   0.568003    0.404481    0.488601    0.483097    0.431211    0.570755
2010-04-15   0.543620    0.385417    0.455078    0.468750    0.408203    0.564453

Я хотел бы получить десятичные числа, округленные до двух цифр и умноженные на 100, например .568003 должно быть 57 возился с ним некоторое время безрезультатно; попробовал это

newdf3.pivot_table(rows=['Quradate'],aggfunc=np.mean).apply(round(2)) #and got:
TypeError: ("'float' object is not callable", u'occurred at index Alabama_exp')

пробовал ряд других подходов безрезультатно большинство жалуются на то, что элемент не является поплавком... Я вижу, что объект серии Pandas имеет круглый метод, но DF не пробовал использовать df.но на это жаловались вопрос поплавка.

4 ответов


просто использовать numpy.round, например:

100 * np.round(newdf3.pivot_table(rows=['Quradate'], aggfunc=np.mean), 2) 

пока круг подходит для всех типов столбцов, это работает на DataFrame.

С некоторыми данными:

In [9]: dfrm
Out[9]:
          A         B         C
0 -1.312700  0.760710  1.044006
1 -0.792521 -0.076913  0.087334
2 -0.557738  0.982031  1.365357
3  1.013947  0.345896 -0.356652
4  1.278278 -0.195477  0.550492
5  0.116599 -0.670163 -1.290245
6 -1.808143 -0.818014  0.713614
7  0.233726  0.634349  0.561103
8  2.344671 -2.331232 -0.759296
9 -1.658047  1.756503 -0.996620

In [10]: 100*np.round(dfrm, 2)
Out[10]:
     A    B    C
0 -131   76  104
1  -79   -8    9
2  -56   98  137
3  101   35  -36
4  128  -20   55
5   12  -67 -129
6 -181  -82   71
7   23   63   56
8  234 -233  -76
9 -166  176 -100

начиная с Pandas 0.17, фреймы данных имеют 'round' способ:

df =newdf3.pivot_table(rows=['Quradate'],aggfunc=np.mean)
df.round()

что даже позволяет иметь различную точность для каждого столбца

df.round({'Alabama_exp':2, 'Credit_exp':3})

для скромного DataFrame, applymap будет ужасно медленно, так как он применяет элемент функции Python по элементам в Python (т. е. нет ускорения Cython). Это быстрее использовать apply С functools.partial:

In [22]: from functools import partial

In [23]: df = DataFrame(randn(100000, 20))

In [24]: f = partial(Series.round, decimals=2)

In [25]: timeit df.applymap(lambda x: round(x, 2))
1 loops, best of 3: 2.52 s per loop

In [26]: timeit df.apply(f)
10 loops, best of 3: 33.4 ms per loop

вы даже можете сделать функцию, которая возвращает частичную функцию, которую вы можете применить:

In [27]: def column_round(decimals):
   ....:     return partial(Series.round, decimals=decimals)
   ....:

In [28]: df.apply(column_round(2))

как @EMS предлагает, вы можете использовать np.round С DataFrame осуществляет __array__ атрибут и автоматически обертывания многие из numpy ' s ufuncs. Это также примерно в два раза быстрее с рамкой, показанной выше:

In [47]: timeit np.round(df, 2)
100 loops, best of 3: 17.4 ms per loop

если у вас есть нечисловые столбцы, вы можете сделать это:

In [12]: df = DataFrame(randn(100000, 20))

In [13]: df['a'] = tm.choice(['a', 'b'], size=len(df))

In [14]: dfnum = df._get_numeric_data()

In [15]: np.round(dfnum)

чтобы избежать загадочной ошибки, вызванной numpy когда вы пытаетесь округлить столбец строк.


я оставляю это здесь для объяснения того, почему подход OP вызвал ошибку, но последующие решения лучше.

лучшее решение-просто использовать Series'round способ:

In [11]: s
Out[11]: 
0    0.026574
1    0.304801
2    0.057819
dtype: float64

In [12]: 100*s.round(2)
Out[12]:  
0     3
1    30
2     6
dtype: float64

вы могли бы лавировать .astype('int') там же, в зависимости от того, что вы хотите делать дальше.

чтобы понять, почему ваш подход не работает, помните, что функция round требуется два аргумента, количество десятичных знаков и данные округляются. В общем, чтобы применить функции, которые принимают два аргумента, вы можете "Карри" функцию так:

In [13]: s.apply(lambda x: round(x, 2))
Out[13]: 
0    1.03
1    1.30
2   -1.06
dtype: float64

как DSM указывает на комментарии, для этого случая действительно нужен подход карринга-потому что нет round метод для фреймов данных. df.applymap(...) - это путь.