как я могу манипулировать десятичными числами в кадре данных панд - PullRequest
0 голосов
/ 05 мая 2018

У меня есть фрейм данных (DF), как это:

euro    token
200.0   65.78947368421053
9997.8  2631.0

Всякий раз, когда есть только .0, я хочу избавиться от .0, но когда в "евро" есть один десятичный знак, например .8, я хочу использовать десятичные дроби, как это обычно бывает с валютой. Таким образом, определение для столбца «евро» будет 2 знака после запятой, кроме случаев, когда есть только 0. Для столбца «токен» это будет 18 знаков после запятой, без показа завершающего 0 и без десятичных знаков, когда есть только 0.

Я много читаю сейчас, но даже не могу найти, с чего начать. Кто-нибудь? * * 1006

Обновленный пример по дальнейшим проблемам

import pandas as pd
import numpy as np

min_invest = 200
cps_exchange_rate_eur = Decimal(38) / Decimal(10)

df = pd.read_excel(file.xlsx,
               index_col=None,
               dtype={'euro': float},
               na_values='NA'
               )

print(df.head())
print(df.dtypes)

      email              euro
0     first@gmail.com    600.00
1     second@web.de      200.00
2     third@web.de       1997.80
3     fourth@gmail.com   200.00
4     fifth@gmx.ch       9997.80

email     object
euro     float64
dtype: object

Теперь я пытаюсь исправить 2 десятичных знака. : -)

df.loc[:, 'euro'] = np.round(df['euro'], decimals=2)
df.loc[:, 'euro_cent'] = (df['euro'] * 100).astype(int)

print(df.head()
print(df.dtypes)

                         email    euro  euro_cent
0              first@gmail.com  600.00      60000
1                second@web.de  200.00      20000
2                 third@web.de  1997.80     199779
3             fourth@gmail.com  200.00      20000
4                 fifth@gmx.ch  9997.80     999779

email         object
euro         float64
euro_cent      int64
dtype: object

Как вы видите, это запутано в строках 2 и 4. Я не могу понять, как это исправить.

Спасибо, Мануэль

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Вы можете следовать по этому пути:

#sample
euro = [2, 2.3, 3.0, 4.0, 5.4444]

new_euro = [round(x) if x == round(x) else "{0:.2f}".format(x) for x in euro]

print(new_euro)
[2, '2.30', 3, 4, '5.44']
0 голосов
/ 05 мая 2018

Если вам нужно, чтобы сохраненные значения были точными с точностью до двух знаков после запятой, то вам следует выполнить арифметику с пакетом decimal. Если вы хотите сохранить полную точность, но вывести на выходе только два десятичных знака, посмотрите различные руководства по форматированию Python, такие как "{:.2f}".format(euro).

.

ОТВЕТ НА КОММЕНТАРИЙ OP

Но посмотрите, как вы получили обменный курс: вы присвоили значение float, так что больше не гарантировано, что оно будет точно 3,8 в базе 10; скорее это самое близкое приближение в двоичном виде. Я получаю 3.79999999999999982236431605997495353221893310546875.

Если вы хотите, чтобы точные были получены в результате того, что вы видите на распечатанной странице, то вы не можете использовать дробные, недвоичные числа в своих вычислениях. Чтобы получить точные 3,8, используйте Decimal(38) / Decimal(10).

ОТВЕТ НА СЛЕДУЮЩИЙ КОММЕНТАРИЙ

Это та же проблема: вы используете входной пакет, который читает тип float, который не имеет того же представления, что и числовые строки в вашем файле. Фракция .8 не может быть представлена ​​точно в двоичном виде. Строки 2 и 4 перепутаны, потому что вы использовали float значения вместо Decimal. Округление до 2 мест не означает, что компьютер теперь может представлять сотые доли; это просто означает, что вы получаете ближайшее доступное значение. Например:

>>> np.round(0.8, 2)
0.80000000000000004

Один из способов справиться с этим - сделать все вашей арифметики - включая начальные значения - в Decimal. Другой способ - принять крошечные ошибки до тех пор, пока не придет время распечатать или записать результаты ... затем округлить до двух знаков после запятой при выходе.

...