¿Por qué se considera a NaN como un flotador?

En pandas cuando intentamos convertir una serie que contiene valores de NaN en enteros con un fragmento de código como el siguiente

df.A = df.A.apply(int) , a menudo veo un mensaje de error

 ValueError: cannot convert float NaN to integer 

Entiendo que los valores de NaN no se pueden convertir a entero. Pero ValueError curiosidad por el ValueError lanzado en este caso. dice que flotante NaN no se puede convertir a entero.

¿Hay alguna razón específica por la que los valores de NaN se traten como objetos flotantes? ¿O es este el caso de algún problema con los mensajes de error mostrados?

La respuesta corta es que IEEE 754 especifica NaN como un valor float .

En cuanto a lo que debe hacer para convertir un pd.Series a tipos de datos numéricos específicos, prefiero usar pd.to_numeric siempre que sea posible. Los siguientes ejemplos demuestran por qué.

 import pandas as pd import numpy as np s = pd.Series([1, 2.5, 3, 4, 5.5]) # s.dtype = float64 s = s.astype(float) # s.dtype = float64 s = pd.to_numeric(s, downcast='float') # s.dtype = float32 t = pd.Series([1, np.nan, 3, 4, 5]) # s.dtype = float64 t = t.astype(int) # ValueError t = pd.to_numeric(t, downcast='integer') # s.dtype = float64 u = pd.Series([1, 2, 3, 4, 5, 6]) # s.dtype = int64 u = u.astype(int) # s.dtype = int32 u = pd.to_numeric(u, downcast='integer') # s.dtype = int8 

Vale la pena pensar en lo que significa decir que cualquier número “es” un float . En CPython, el tipo float se implementa utilizando double en C, lo que significa que usan doble precisión IEEE 754 .

En esa norma, hay secuencias de bits particulares que corresponden a cada número de punto flotante que se puede representar en el sistema (tenga en cuenta que no se pueden representar todos los números posibles entre los límites superior e inferior).

Además, hay un par de secuencias de bits especiales que no corresponden a números “regulares” y, por lo tanto, no se pueden convertir a un entero.

  • Dos infinitos: + ∞ y −∞.
  • Dos tipos de NaN : un NaN silencioso ( qNaN ) y un NaN señalización ( sNaN ).

Para construir un float con tales valores, puede utilizar esta llamada:

 nan = float('nan') inf = float('inf') 

Y puede ver el mismo error al pasar estos valores al constructor int :

 >>> int(nan) ValueError: cannot convert float NaN to integer >>> int(inf) OverflowError: cannot convert float infinity to integer