Pandas округление не работает при указании типов данных? - PullRequest
1 голос
/ 17 апреля 2020

У меня проблема с тем, что pandas.round() не работает должным образом после определения моих собственных типов данных. Я использую v. 0.24.2.

Скажите, что у меня есть данные как float64, и я хочу, чтобы мои данные были float32, чтобы сэкономить память, и я хочу сделать некоторое округление:

import pandas as pd

my_dtypes = {'val': 'float32'}
my_decimals = {'val': 4}

df = pd.DataFrame({'val': [0.14579999446868896]}) # <- this will be 'float64' 
df_mydtypes = df.astype(my_dtypes)

df_rounded = df.round(my_decimals)
df_mydtypes_rounded = df_mydtypes.round(my_decimals)

Можно ожидать, что результат округляется до 0.1458 после округления до 4 знаков после запятой.

print(df_rounded['val'])
print(df_mydtypes_rounded['val'])

print(df_rounded['val'].item())
print(df_mydtypes_rounded['val'].item())

На поверхности это выглядит хорошо, но если мы посмотрим ближе (как это делал мой unittest ) значение другое:

0    0.1458
Name: val, dtype: float64
0    0.1458
Name: val, dtype: float32
0.1458
0.14579999446868896

Что здесь происходит?

1 Ответ

1 голос
/ 17 апреля 2020

Я считаю, что это связано с более общей проблемой в области компьютерных наук, а также с тем, как хранятся числа с плавающей запятой. См. "Арифметика с плавающей точкой c: проблемы и ограничения" в Python документах для подробного объяснения.

Некоторые способы справиться с этим:

  • Я заметил, что .values или .iloc do дают правильное число, но to_list() и .item() не делайте. Я предполагаю, что это связано с тем, как pandas обрабатывает и создает базовые массивы numpy.
  • Python также имеет модуль decimal на случай, если вам нужно ' люди плавают вместо компьютерных ...
...