Как получить «истинную» точность десятичных знаков с помощью pandas round?

#python #pandas #numpy #rounding

#python #pandas #numpy #округление

Вопрос:

Чего мне не хватает? Я попытался добавить .round(3) в конец вызова api, но это не работает, а также не работает в отдельных вызовах. Типы данных для всех столбцов numpy.float32 .

 >>> summary_data = api._get_data(units=list(units.id),
                             downsample=downsample,
                             table='summary_tb',
                             db=db).astype(np.float32)
>>> summary_data.head()


    id  asset_id    cycle   hs      alt     Mach        TRA         T2
0   10.0    1.0     1.0     1.0     3081.0  0.37945     70.399887   522.302124
1   20.0    1.0     1.0     1.0     3153.0  0.38449     70.575668   522.428162
2   30.0    1.0     1.0     1.0     3229.0  0.39079     70.575668   522.645020
3   40.0    1.0     1.0     1.0     3305.0  0.39438     70.575668   522.651184
4   50.0    1.0     1.0     1.0     3393.0  0.39690     70.663559   522.530090

>>> summary_data = summary_data.round(3)
>>> summary_data.head()

    id  asset_id    cycle   hs      alt     Mach    TRA         T2
0   10.0    1.0     1.0     1.0     3081.0  0.379   70.400002   522.302002
1   20.0    1.0     1.0     1.0     3153.0  0.384   70.575996   522.427979
2   30.0    1.0     1.0     1.0     3229.0  0.391   70.575996   522.645020
3   40.0    1.0     1.0     1.0     3305.0  0.394   70.575996   522.651001
4   50.0    1.0     1.0     1.0     3393.0  0.397   70.664001   522.530029


>>> print(type(summary_data))

pandas.core.frame.DataFrame

>>> print([type(summary_data[col][0]) for col in summary_data.columns])

[numpy.float32,
 numpy.float32,
 numpy.float32,
 numpy.float32,
 numpy.float32,
 numpy.float32,
 numpy.float32,
 numpy.float32]

 

На самом деле похоже, что происходит какая-то форма округления, но происходит что-то странное. Заранее спасибо.

Редактировать

Суть в том, чтобы использовать 32-разрядные числа с плавающей запятой, а не 64-разрядные. С тех пор я использовал pd.set_option('precision', 3) , но, согласно документации, это влияет только на отображение, но не на базовое значение. Как упоминалось в комментарии ниже, я пытаюсь минимизировать количество атомарных операций. Вычисления на 70.575996 против 70.57600 стоят дороже, и это проблема, которую я пытаюсь решить. Заранее спасибо.

Ответ №1:

Хм, это может быть проблема с плавающей запятой. Вы могли бы изменить dtype на float вместо np.float32 :

 >>> summary_data.astype(float).round(3)
     id  asset_id  cycle   hs     alt   Mach     TRA       T2
0  10.0       1.0    1.0  1.0  3081.0  0.379  70.400  522.302
1  20.0       1.0    1.0  1.0  3153.0  0.384  70.576  522.428
2  30.0       1.0    1.0  1.0  3229.0  0.391  70.576  522.645
3  40.0       1.0    1.0  1.0  3305.0  0.394  70.576  522.651
4  50.0       1.0    1.0  1.0  3393.0  0.397  70.664  522.530
 

Если вы измените его обратно на np.float32 впоследствии, проблема снова возникнет:

 >>> summary_data.astype(float).round(3).astype(np.float32)
     id  asset_id  cycle   hs     alt   Mach        TRA          T2
0  10.0       1.0    1.0  1.0  3081.0  0.379  70.400002  522.302002
1  20.0       1.0    1.0  1.0  3153.0  0.384  70.575996  522.427979
2  30.0       1.0    1.0  1.0  3229.0  0.391  70.575996  522.645020
3  40.0       1.0    1.0  1.0  3305.0  0.394  70.575996  522.651001
4  50.0       1.0    1.0  1.0  3393.0  0.397  70.664001  522.530029
 

Комментарии:

1. Спасибо за ваш ответ. Из того, что я знаю, float это двойной тип c и использует 64 байта памяти, и я пытаюсь использовать 32 байта. Похоже, что вторая ссылка, предоставленная модератором выше, «кажется» решает мою проблему, но у меня есть дополнительные вопросы, касающиеся затрат на вычисления, которые я пытаюсь уменьшить. Приводит ли 70.575996 к большему количеству атомарных операций, чем 70.576? Да, это так. Но, согласно pandas, pd.set_option('precision', 3) влияет только на отображение, а не на базовое значение. Так что мой вопрос, казалось бы, в некотором смысле все еще актуален.

2. Хорошо, звучит интересно. Если ваш вопрос уникален, уточните это в теле вопроса, и мы, вероятно, сможем открыть его повторно. (Кстати, Генри Экер не модератор — он просто обычный пользователь с золотым значком Python, который позволяет ему закрывать вопросы с помощью тега Python дубликатами других с этим тегом, не требуя одобрения других пользователей, потому что предполагается, что он достаточно опытен 🙂

3. биты, а не байты ^^

4. Похоже, вопрос был открыт заново, спасибо! Я возвращаюсь к этому сейчас в своем проекте и вспомнил, зачем мне это нужно. Какие-либо обновления?