В чем разница между NaN и None в Python
Что проверяют
Умеете ли вы работать с пропусками в данных, а не только отличать два объекта в чистом Python. На data-ml собеседовании почти сразу следует уточнение: во что превратится None в колонке pandas и как посчитать пропуски в датафрейме.
Как отвечать
Начните с природы значений:
None: единственный экземплярNoneType, «значения нет» на уровне языка. Проверяется черезis None, в арифметике падает сTypeError;NaN: специальное значениеfloatиз стандарта IEEE 754, результат неопределённой операции вроде0 * inf.np.nanэто обычный питоновскийfloat, а не отдельный тип NumPy. Главное свойство:NaNне равен ничему, даже себе, поэтомуx == np.nanвсегдаFalse.
Дальше переходите к pandas, ради этого и спрашивают:
- в числовой колонке
Noneпри создании превращается вNaN, а целочисленная колонка с пропуском становитсяfloat64; - в колонке
objectNoneостаётсяNone, и в одной колонке могут жить оба вида пропусков; pd.isna()иdf.isna().sum()ловят иNone, иNaN, иNaTдля дат, поэтому проверять лучше ими;- агрегаты pandas по умолчанию пропуски игнорируют (
skipna=True), аnp.meanна массиве сNaNвернётNaN, для этого естьnp.nanmean; - nullable-типы
Int64,boolean,stringиспользуютpd.NAи позволяют держать целые числа с пропусками без перехода воfloat.
Хорошо закончить практикой: NaN может означать и «не заполнили», и «деление на ноль при расчёте признака», а для импутации это разные случаи.
Где спотыкаются
Фильтруют пропуски через df[df.col == np.nan] и получают пустой результат. Нужен isna().
Считают np.isnan() универсальной проверкой. На None и на строках он падает с TypeError, в колонке object он бесполезен.
Не замечают, что после появления пропуска колонка с идентификаторами стала float64, и при джойне или выгрузке 123 превращается в 123.0. Лечится явным astype("Int64").