2016-10-06 7 views
4

У меня есть список поплавков (на самом деле это объект панды серии, если он меняет что-нибудь), который выглядит следующим образом:Назначения поплавка в качестве словаря ключа изменяет свою точность (Python)

mySeries: 

... 
22  16.0 
23  14.0 
24  12.0 
25  10.0 
26  3.1 
... 

(Так элементы эта серия справа, индексы слева) Тогда я пытаюсь присвоить элементы из этой серии в качестве ключей в словаре, и индексы в качестве значений, например:.

{ mySeries[i]: i for i in mySeries.index } 

и я получая в значительной степени то, что я хотел, кроме того, что ...

{ 6400.0: 0, 66.0: 13, 3.1000000000000001: 23, 133.0: 10, ... } 

Почему 3.1 вдруг изменился на 3.1000000000000001? Я предполагаю, что это имеет отношение к тому, как представлены числа с плавающей запятой (?), Но почему это происходит сейчас и как его избежать/исправить?

EDIT: Пожалуйста, не стесняйтесь предлагать лучшее название для этого вопроса, если оно неточно.

EDIT2: Хорошо, так что кажется, что это точно такой же номер, только напечатаны по-разному. Тем не менее, если я назначу mySeries[26] в качестве словаря ключ, а затем я пытаюсь запустить:

myDict[mySeries[26]] 

я KeyError. Каков наилучший способ избежать этого?

+0

пытались ли вы MySeries.astype (поплавок) .to_dict() –

+0

@StevenG Я пытаюсь это сделать наоборот: иметь индексы в качестве значений. Во всяком случае, я не думаю, что это решило бы эту проблему. – machaerus

ответ

6

Словарь не меняет представление с плавающей запятой 3.1, но фактически отображает полную точность. Ваша печать mySeries [26] усекает точность и показывает приближение.

Вы можете доказать это:

pd.set_option('precision', 20) 

Затем просмотрите mySeries.

0 16.00000000000000000000 
1 14.00000000000000000000 
2 12.00000000000000000000 
3 10.00000000000000000000 
4  3.10000000000000008882 
dtype: float64 

EDIT:

What every computer programmer should know about floating point arithmetic всегда хорошо читать.

EDIT:

Что касается исключения KeyError, я не был в состоянии воспроизвести проблему.

>> x = pd.Series([16,14,12,10,3.1]) 
>> a = {x[i]: i for i in x.index} 
>> a[x[4]] 
4 
>> a.keys() 
[16.0, 10.0, 3.1000000000000001, 12.0, 14.0] 
>> hash(x[4]) 
2093862195 
>> hash(a.keys()[2]) 
2093862195 
+0

См. Мою последнюю редакцию. – machaerus

3

Значение уже этак в серии:

>>> x = pd.Series([16,14,12,10,3.1]) 
>>> x 
0 16.0 
1 14.0 
2 12.0 
3 10.0 
4  3.1 
dtype: float64 
>>> x.iloc[4] 
3.1000000000000001 

Это связано с числами с плавающей запятой:

>>> np.float64(3.1) 
3.1000000000000001 

См Floating point precision in Python array для получения дополнительной информации об этом.

Относительно KeyError в вашем редактировании я не смог воспроизвести. Смотрите ниже:

>>> d = {x[i]:i for i in x.index} 
>>> d 
{16.0: 0, 10.0: 3, 12.0: 2, 14.0: 1, 3.1000000000000001: 4} 
>>> x[4] 
3.1000000000000001 
>>> d[x[4]] 
4 

Мои подозрения в том, что KeyError исходит из Series: что mySeries[26] возвращение?

+0

Я отредактировал мой вопрос, пожалуйста, посмотрите. – machaerus

+0

@machaerus отредактировал с дополнительной информацией – brianpck

+1

Спасибо @brianpck, вы правы, проблема действительно была вызвана чем-то другим в моем коде (не связанным с представлением с плавающей запятой). Серия Pandas отлично работает. – machaerus

Смежные вопросы