Я взял строку из фрейма данных, которая выглядит следующим образом:
https://i.stack.imgur.com/Y9LUE.png
или
Clicks Spend clk_ar CPC AdRank temp tempRan
36.0 248.76 59.94 6.91 1.67 1.665 1.67
Мне нужно округлить значения двумя цифрами в столбце temp
Опция 1:
round(df.temp,2)
OUTPUT:
1676725 1.66
Name: temp, dtype: float64
Вариант 2:
df.temp.apply(lambda x:round(x,2))
OUTPUT:
1676725 1.67
Name: temp, dtype: float64
Две функции раунда показывают разное поведение. Очевидно, что вариант 1 соответствует поведению Python 3. См. Поведение округления Python 3.x
Мне просто интересно, почему вариант 2 так себя ведет. Спасибо за вашу помощь!
Немного удивляет меня то, что извлечение значений из Pandas Series
с dtype np.float64
дает реальные объекты Python float
, а не объекты NumPy float64
. (Два раунда по-разному на Python 3 даже при использовании встроенной функции Python round
.)
За исключением того, что если вы извлекаете значения из напрямую посредством индексации, вы делать получаете экземпляры np.float64
вместо экземпляров float
. Только под apply
вы таинственным образом получаете обычные float
. Ага!
Я думаю, причина здесь в numpy docs
Notes
For values exactly halfway between rounded decimal values, NumPy rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0, -0.5 and 0.5 round to 0.0, etc. Results may also be surprising due to the inexact representation of decimal fractions in the IEEE floating point standard [1] and errors introduced when scaling by powers of ten.
В варианте 1 вы округляете numpy.float, который использует правила about.
В варианте 2 вы округляете тип данных Python с плавающей запятой документы здесь.
Удовольствие с арифметикой с плавающей запятой:
round(1.675, 2)
1.68
round(2.675, 2)
2.67
Это более тонко, чем это. Фактически, round
Python во всех случаях следует правилу «ближайших связей к четным», а NumPy - нет. Но из-за обычной природы двоичной с плавающей запятой «То, что вы видите, не то, что вы получаете», фактически округляемое значение - это вовсе не половина дела. На типичной машине фактическое округляемое значение будет 1.66500000000000003552713678800500929355621337890625
, которое следует округлить в большую сторону.
@MarkDickinson Спасибо за эту информацию и понимание.
Да, прости; Я излишне придираюсь; разница в том, как вы заявляете, что мы округляем экземпляры NumPy float64
по сравнению с обычными float
на Python, хотя это немного загадка, почему мы получаем обычные float
для Python из Series
с dtype np.float64
.
@MarkDickinson Не нужно извиняться, я ценю такие идеи. Еще раз спасибо.
См. Также здесь.