Pandas round в некоторых случаях обрезается

Я использую следующий код, и, как вы можете видеть во 2-й строке, округление правильное, а в 3-й строке данные усекаются.

import pandas as pd
import numpy as np

data = [[11,10],[17.50,11.01],[21.95,22.5]]
df = pd.DataFrame(data,columns=['A','B'])

df['avg'] = df[["A", "B"]].mean(axis=1)
df['avg_round'] = df['avg'].apply(lambda x: np.round(x, decimals=2)) 

Pandas round в некоторых случаях обрезается

Я тоже пробовал это, и результаты идентичны:

df['avg] = df[["A", "B"]].mean(axis=1).round(2)

Разве это не проблема отображения? значения верны, просто не отображаются конечные нули

EdChum 01.05.2018 12:46

Нет, 22,225 следует округлить до 22,23, но здесь 22,22.

Nikhil Ratna Shakya 01.05.2018 13:49

@NikhilRatnaShakya: 22.225 действительно следует округлить до 22.23, но не по тем причинам, которые вы думаете. Pandas (и NumPy, и Python) использует формат с плавающей запятой двоичный. То, что выглядит как 22.225, на самом деле сохраняется как 22.22500000000000142108547152020037174224853515625. Поскольку это строго больше, чем 22.225, оно действительно должно округляться. NumPy / Pandas не выполняет здесь идеально правильное округление, но в первую очередь неразумно полагаться на результаты десятичного представления двоичного приближения к десятичному округлению двоичного приближения к десятичному половинному регистру.

Mark Dickinson 01.05.2018 22:29
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
629
1

Ответы 1

Это не проблема панд. Посмотрите фактические значения avg:

>>> df['avg'][1] 
   14.254999999999999
>>> df['avg'][2]
   22.225000000000001

Если вы используете:

df['avg_round'] = df['avg'].apply(lambda x: round(x, 2))

Вы получите 14.25 и 22.23 - один округляется в большую сторону, а другой в меньшую из-за представления с плавающей запятой. Однако раунд Numpy даст вам 14.26 и 22.22, потому что в таких случаях он округляется до ближайшего числа четный. Как указано в документы:

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 [R1011] and errors introduced when scaling by powers of ten.

Я пробовал это со средним значением [22,5,21,99], которое составляет 22,245, и в итоге получил 22,24. Номер хранился как 22,244999999999997. Я попытался округлить до 4 цифр, а затем снова до 2, и это сработало. Однако я не уверен, правильный ли это путь.

Nikhil Ratna Shakya 01.05.2018 13:45

@NikhilRatnaShakya - это ожидаемое поведение раунда numpy. Если вам не нравится, как это работает, используйте ceil.

nbubis 01.05.2018 13:49

округление до четности здесь не имеет значения: оно применяется только к точным связям, а это не одно: фактическое значение, сохраненное для 22.225, почти наверняка будет 22.22500000000000142108547152020037174224853515625, которое будет округлено вверх функцией round, которая выполняет правильное округление. Функция round NumPy не выполняет правильное округление. Однако у Python есть, и в чистом Python вы получите round(22.225, 2), предоставляющий 22.23.

Mark Dickinson 01.05.2018 22:24

Другие вопросы по теме