Pandas: ¿Por qué es el tipo de columna predeterminado para el flotador numérico?

Estoy usando Pandas 0.18.1 con python 2.7.x. Tengo un dataframe vacío que leí primero. Veo que los tipos de estas columnas son object que está bien. Cuando asigno una fila de datos, el tipo de valores numéricos cambia a float64 . Esperaba int o int64 . ¿Por qué pasó esto?

¿Hay alguna forma de establecer alguna opción global para que Pandas sepa que para los valores numéricos, trátelos de forma predeterminada como int menos que los datos tengan un . ? Por ejemplo, [0 1.0, 2.] , la primera columna es int pero las otras dos son float64 ?

Por ejemplo:

 >>> df = pd.read_csv('foo.csv', engine='python', keep_default_na=False) >>> print df.dtypes bbox_id_seqno object type object layer object ll_x object ll_y object ur_x object ur_y object polygon_count object dtype: object >>> df.loc[0] = ['a', 'b', 'c', 1, 2, 3, 4, 5] >>> print df.dtypes bbox_id_seqno object type object layer object ll_x float64 ll_y float64 ur_x float64 ur_y float64 polygon_count float64 dtype: object 

No es posible que Pandas almacene valores de NaN en columnas enteras.

Esto hace que float sea ​​la opción obvia por defecto para el almacenamiento de datos, ya que tan pronto como surja el valor faltante, Pandas tendría que cambiar el tipo de datos para toda la columna. Y los valores faltantes surgen muy a menudo en la práctica.

En cuanto a por qué esto es, es una restricción heredada de Numpy. Básicamente, las pandas necesitan apartar un patrón de bits particular para representar NaN . Esto es sencillo para los números de punto flotante y se define en el estándar IEEE 754. Es más incómodo y menos eficiente hacer esto para un entero de ancho fijo.

Actualizar

Buenas noticias en pandas 0.24. IntegerArray es una característica experimental, pero podría dejar obsoleta mi respuesta original. Entonces, si estás leyendo esto en o después del 27 de febrero de 2019, revisa la documentación para esa característica.

Si está leyendo un dataframe vacío, puede convertir explícitamente los tipos para cada columna después de leerlo.

 dtypes = { 'bbox_id_seqno': object, 'type': object, 'layer': object, 'll_x': int, 'll_y': int, 'ur_x': int, 'ur_y': int, 'polygon_count': int } df = pd.read_csv('foo.csv', engine='python', keep_default_na=False) for col, dtype in dtypes.iteritems(): df[col] = df[col].astype(dtype) df.loc[0] = ['a', 'b', 'c', 1, 2, 3, 4, 5] >>> df.dtypes bbox_id_seqno object type object layer object ll_x int64 ll_y int64 ur_x int64 ur_y int64 polygon_count int64 dtype: object 

Si no conoce los nombres de las columnas en su dataframe vacío, inicialmente puede asignar todo como un int y luego dejar que Pandas lo resuelva.

 for col in df: df[col] = df[col].astype(int) 

El por qué es casi seguro que tiene que ver con la flexibilidad y la velocidad. El hecho de que Pandas solo haya visto un número entero en esa columna hasta ahora no significa que no vaya a intentar agregar un flotante más adelante, lo que requeriría que Pandas regrese y cambie el tipo de toda esa columna. Un flotador es el tipo numérico más robusto / flexible.

No hay una forma global de anular ese comportamiento (que yo sepa), pero puede usar el método astype para modificar un DataFrame individual.

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.astype.html