Почему Pandas / Numpy автоматически округляет 9999999999 до 1.000000e + 10? - PullRequest
2 голосов
/ 24 апреля 2019

У меня есть кадр данных Pandas с 4 строками, и один из столбцов (с именем limit) содержит значения с плавающей запятой, где любые нули должны быть заменены на 9999999999 (9,9999999999 миллиардов). В столбце указан тип данных float32, и я использую метод pandas.DataFrame.where для замены. Но он работает не так, как ожидалось, потому что Numpy округляет 9999999999 до 10000000000 (10 миллиардов).

Я пробовал это в iPython 3 (Python 3.6.8), Pandas версии 0.24.2, Numpy версии 1.14.0.

Это заявление о замене

df['limit'] = df['limit'].where(df['limit'] != 0, 9999999999)

Я вижу следующие значения столбца для limit:

0    1.000000e+10
1    1.000000e+10
2    1.000000e+10
3    1.000000e+10

но я ожидаю

0    9999999999.0
1    9999999999.0
2    9999999999.0
3    9999999999.0

Почему происходит округление? Этого не происходит с простым Python

In [1]: (9.999999999) * 10**9                                                                                                    
Out[1]: 9999999999.0

1 Ответ

2 голосов
/ 24 апреля 2019

Это просто потому, что int32 не способен сохранить это число.Вы можете проверить это, рассчитав количество битов, необходимых для демонстрации этого числа:

In [24]: np.floor(np.log2(9999999999)) + 1
Out[24]: 34.0

Как видите, для демонстрации этого числа вам нужно как минимум 34 бита.Поэтому вы должны использовать int64 в качестве большего типа данных для его представления.

Даже если вы протестируете это, поместив число в серию с тем же типом данных, вы снова увидите неожиданный результат (переполнение):

In [25]: s = pd.Series([9999999999], dtype=pd.np.int32)

In [26]: s
Out[26]: 
0    1410065407
dtype: int32
...