Почему при преобразовании строк числовые значения усекаются? - PullRequest
0 голосов
/ 16 мая 2018

Сотрудник, и я заметил кое-что странное в numpy, которое мы не понимаем. Это происходит с использованием Python 3.5.4 и numpy версии 1.14.2-py35ha9ae307_1 (плюс более ранняя версия, которую я обновил на всякий случай).

Похоже, проблема заключается в том, что если добавить массив с плавающей точкой вместе с некоторыми строками, он, как и ожидалось, преобразуется в строку, но иногда (очень редко) с плавающей точкой происходит очень странное усечение. Я не знаю, это ошибка или просто какое-то поведение, которое мы не понимаем. В любом случае это кажется странным. Любое понимание было бы полезно.

Воспроизводимый пример

import numpy as np
p = np.empty([1,2],dtype='U21')
a = 4.4226657709978134e-05
p[0] = np.array(['string',a])
p

# WTF
Out[5]: array([['string', '4.4226657709978134e-0']], dtype='<U21')

Зависит от последней цифры числа с плавающей запятой

# Works as expected
In [26]: np.array(['string',4.4226657709978130e-05], dtype='<U21')
Out[26]: array(['string', '4.422665770997813e-05'], dtype='<U21')

# Works as expected
In [27]: np.array(['string',4.4226657709978131e-05], dtype='<U21')
Out[27]: array(['string', '4.422665770997813e-05'], dtype='<U21')

# Doesn't work as expected
In [28]: np.array(['string',4.4226657709978132e-05], dtype='<U21')
Out[28]: array(['string', '4.4226657709978134e-0'], dtype='<U21')

# Doesn't work as expected
In [29]: np.array(['string',4.4226657709978133e-05], dtype='<U21')
Out[29]: array(['string', '4.4226657709978134e-0'], dtype='<U21')

# Doesn't work as expected
In [30]: np.array(['string',4.4226657709978134e-05], dtype='<U21')
Out[30]: array(['string', '4.4226657709978134e-0'], dtype='<U21')

# Doesn't work as expected
In [31]: np.array(['string',4.4226657709978135e-05], dtype='<U21')
Out[31]: array(['string', '4.4226657709978134e-0'], dtype='<U21')

# Doesn't work as expected
In [32]: np.array(['string',4.4226657709978136e-05], dtype='<U21')
Out[32]: array(['string', '4.4226657709978134e-0'], dtype='<U21')

# Doesn't work as expected
In [33]: np.array(['string',4.4226657709978137e-05], dtype='<U21')
Out[33]: array(['string', '4.4226657709978134e-0'], dtype='<U21')

# Works as expected
In [34]: np.array(['string',4.4226657709978138e-05], dtype='<U21')
Out[34]: array(['string', '4.422665770997814e-05'], dtype='<U21')

# Works as expected
In [35]: np.array(['string',4.4226657709978139e-05], dtype='<U21')
Out[35]: array(['string', '4.422665770997814e-05'], dtype='<U21')

Проблема тривиальна для решения, например, путем переключения на фрейм данных Pandas, который может иметь дело с различными типами. Но поведение кажется странным. Мы заметили это только потому, что делали это на миллионах чисел, и проверки работоспособности выделили это (все наши числа должны быть <1, и мы очень редко начинали получать числа> 1).

Ответы [ 2 ]

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

Если вы хотите смешивать строки и числа с плавающей точкой в ​​массиве, который вы не используете, используйте pandas. Объект dtype работает (это то, что pandas использует)

In [394]: a = 4.4226657709978134e-05
In [395]: np.array(['string',a])
Out[395]: array(['string', '4.4226657709978134e-05'], dtype='<U22')
In [396]: np.array(['string',a], object)
Out[396]: array(['string', 4.4226657709978134e-05], dtype=object)

Или структурированный dtype:

In [398]: np.array([('string',a)],'U10,float')
Out[398]: array([('string', 4.42266577e-05)], dtype=[('f0', '<U10'), ('f1', '<f8')])
In [399]: _.item()
Out[399]: ('string', 4.4226657709978134e-05)
0 голосов
/ 16 мая 2018

На самом деле это не что-то о Нампи. Смотри https://stackoverflow.com/a/25899600/982257

Python (3) обычно представляет числа с плавающей точкой как строки с наименьшим количеством цифр, необходимых для однозначного представления этого конкретного значения с плавающей точкой.

В случаях 4.4226657709978137e-05 и 4.4226657709978138e-05 ни то, ни другое точно не представлено двойными значениями IEEE. В случае 4.4226657709978137e-05 его кратчайшее однозначное представление составляет всего 22 символа, а не 21, поэтому при попытке вставить его в <U21 оно усекается.

Для представления большинства парных чисел в научной нотации требуется не менее 24 символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...