В чем разница между NaN и None?

97

Я читаю два столбца файла csv, используя pandas, readcsv()а затем присваиваю значения словарю. Столбцы содержат строки цифр и букв. Иногда бывают случаи, когда ячейка пуста. На мой взгляд, значение, считываемое этой словарной статье, должно быть, Noneно вместо этого nanприсваивается. Конечно, Noneэто более наглядно для пустой ячейки, поскольку она имеет нулевое значение, тогда как nanпросто говорит, что прочитанное значение не является числом.

Я правильно понимаю, в чем разница между Noneи nan? Почему nanназначается вместо None?

Кроме того, моя проверка словаря на наличие пустых ячеек использовала numpy.isnan():

for k, v in my_dict.iteritems():
    if np.isnan(v):

Но это дает мне сообщение о том, что я не могу использовать эту проверку для v. Я предполагаю, что это потому, что предполагается использовать целочисленную или плавающую переменную, а не строку. Если это правда, как я могу проверить vналичие «пустой ячейки» / nanслучая?

user1083734
источник
Текст qwerty- это не число.
Роберт Харви
1
@RobertHarvey Я знаю, так что наверняка Noneбыло бы лучше описать значение пустой ячейки.
user1083734 08

Ответы:

110

NaN используется в качестве заполнителя для отсутствующих данных последовательно в панде , консистенция хорошая. Я обычно читаю / перевожу NaN как «отсутствующий» . Также см. Раздел «Работа с отсутствующими данными» в документации.

Уэс пишет в документах «Выбор NA-представления» :

После многих лет производственного использования [NaN] оказалось, по крайней мере, на мой взгляд, лучшим решением, учитывая состояние дел в NumPy и Python в целом. Специальное значение NaN (Not-A-Number) используется везде в качестве значения NA, и есть функции API , isnullи notnullкоторые могут быть использованы через dtypes для обнаружения значения NA.
...
Таким образом, я выбрал подход Pythonic «практичность превосходит чистоту» и обменял возможности целочисленного NA на гораздо более простой подход, заключающийся в использовании специального значения в массивах с плавающей запятой и объектных массивах для обозначения NA и переводе целочисленных массивов в плавающие, когда NA должны быть введен.

Примечание: ошибка в том, что целочисленные серии, содержащие отсутствующие данные, преобразуются в числа с плавающей запятой .

На мой взгляд, основная причина использования NaN (вместо None) заключается в том, что его можно сохранить с помощью numpy float64 dtype, а не менее эффективного объекта dtype, см. Продвижение типов NA .

#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Джефф комментирует это (ниже):

np.nanпозволяет векторизовать операции; это значение с плавающей запятой, в то время как None, по определению, задает тип объекта, что в основном отключает всю эффективность в numpy.

Так что повторите 3 раза быстро: object == bad, float == good

При этом многие операции могут работать так же хорошо с None vs NaN (но, возможно, не поддерживаются, т.е. иногда могут давать удивительные результаты ):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

Чтобы ответить на второй вопрос:
вы должны использовать pd.isnullи pd.notnullдля проверки отсутствующих данных (NaN).

Энди Хайден
источник
19
просто добавив здесь 2c .... np.nanразрешает векторизацию операций; это значение с плавающей запятой, в то время как Noneпо определению objectпринудительно вводит тип и в основном отключает всю эффективность в numpy, поэтому повторите 3 раза быстро:object==bad, float==good
Джефф
1
Есть <NA>также np.nan?
Гатид
18

NaNможет использоваться как числовое значение для математических операций, но Noneне может (или, по крайней мере, не должно).

NaN- числовое значение, как определено в стандарте IEEE 754 с плавающей запятой . Noneявляется внутренним типом Python ( NoneType) и в этом контексте больше походил бы на «несуществующий» или «пустой», чем на «числовой недействительный».

Главный «симптом» этого заключается в том, что если вы выполняете, скажем, среднее значение или сумму для массива, содержащего NaN, даже одного, в результате вы получите NaN ...

С другой стороны, вы не можете выполнять математические операции, используя в Noneкачестве операнда.

Таким образом, в зависимости от случая вы можете использовать его Noneкак способ указать своему алгоритму не учитывать недопустимые или несуществующие значения при вычислениях. Это означало бы, что алгоритм должен проверять каждое значение, чтобы убедиться, что это так None.

У Numpy есть несколько функций, позволяющих избегать значений NaN, которые могут испортить ваши результаты, например, nansumи nan_to_num.

Heltonbiker
источник
Я согласен с вами, что None следует использовать для несуществующих записей, так почему же df=pd.readcsv('file.csv')выдает мне NaNзначения для пустых ячеек, а не None? Насколько мне известно, pd.DataFrames не являются исключительными для чисел.
user1083734 08
Что ж, вероятно, это выбор дизайна. Я полагаю, что DataFrames и Series имеют a dtype, поэтому недопустимые значения dtype=floatдолжны быть представлены числовыми значениями, которые NaNесть и Noneне являются ( Noneесть NoneType).
heltonbiker 08
Кроме того, у многих методов Pandas есть naаргумент, который позволяет вам решить, какое значение вы собираетесь использовать для замены недоступных значений
heltonbiker 08
Хорошо, спасибо. Поэтому я на самом деле читаю не числа в свой DataFrame, а строки цифр и букв. Какой вид проверки мне следует использовать для обнаружения пустых ячеек? Проверить лайк; если dtype == float: ??
user1083734 08
Возможно, вам поможет публикация образца ваших данных CSV. Я могу себе представить, что если есть строки, то dtype будет строкой для всего столбца (серии). Но, возможно, если не каждая строка имеет одинаковое количество столбцов, вы получите недоступные данные. Думаю, тебе придется это проверить.
heltonbiker 08
3

Функция isnan()проверяет, является ли что-то «Не числом», и возвращает значение, является ли переменная числом, например isnan(2), возвращает ложь.

Условное myVar is not Noneвыражение возвращает независимо от того, определена ли переменная.

Ваш массив numpy использует, isnan()потому что он предназначен для массива чисел и инициализирует все элементы массива, чтобы NaNэти элементы считались "пустыми"

Стефан
источник
1
Думаю isnan(2), вернусь False, так как 2 не NaN.
heltonbiker 08
Кроме того, numpy.emptyне инициализирует значения массива NaN. Он просто вообще не инициализирует значения.
heltonbiker 08
5
Правильная проверка на наличие None- myVar is not Noneнет myVar != None.
Jaime
3
Обратите внимание, что np.isnan()это не реализовано для строковых переменных, поэтому, если вы передадите ему строку, произойдет сбой. Лучше использовать тот, pd.isnullкоторый работает со строками.
Майкл
-1

Ниже приведены отличия:

  • nan принадлежит к классу float
  • None принадлежит к классу NoneType

Я нашел следующую статью очень полезной: https://medium.com/analytics-vidhya/dealing-with-missing-values-nan-and-none-in-python-6fc9b8fb4f31

эшвара амиртхан с
источник
Хотя эта ссылка может дать ответ на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если ссылка на страницу изменится. - Из
отзыва
@ A.Kootstra, я понимаю
eswara amirthan s
-3

NaNозначает НЕ число .
Noneможет означать любой .

Диегоагилар
источник