Округление записей в кадре 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(...)
- это путь.