tablas renombrar para nombre libreria leer graficar funciones filtrar datos con columnas columna cambiar python pandas dataframe types casting

renombrar - pandas python



Cambiar el tipo de datos de las columnas en Pandas. (6)

¿Qué tal crear dos marcos de datos, cada uno con diferentes tipos de datos para sus columnas, y luego agregarlos juntos?

d1 = pd.DataFrame(columns=[ ''float_column'' ], dtype=float) d1 = d1.append(pd.DataFrame(columns=[ ''string_column'' ], dtype=str))

Resultados

In[8}: d1.dtypes Out[8]: float_column float64 string_column object dtype: object

Después de crear el marco de datos, puede poblarlo con variables de punto flotante en la primera columna y cadenas (o cualquier tipo de datos que desee) en la segunda columna.

Quiero convertir una tabla, representada como una lista de listas, en un DataFrame de Pandas. Como un ejemplo extremadamente simplificado:

a = [[''a'', ''1.2'', ''4.2''], [''b'', ''70'', ''0.03''], [''x'', ''5'', ''0'']] df = pd.DataFrame(a)

¿Cuál es la mejor manera de convertir las columnas a los tipos apropiados, en este caso las columnas 2 y 3 en flotantes? ¿Hay una manera de especificar los tipos al convertir a DataFrame? ¿O es mejor crear el DataFrame primero y luego recorrer las columnas para cambiar el tipo de cada columna? Idealmente, me gustaría hacer esto de forma dinámica porque puede haber cientos de columnas y no quiero especificar exactamente qué columnas son de qué tipo. Todo lo que puedo garantizar es que cada columna contiene valores del mismo tipo.


¿Qué tal esto?

a = [[''a'', ''1.2'', ''4.2''], [''b'', ''70'', ''0.03''], [''x'', ''5'', ''0'']] df = pd.DataFrame(a, columns=[''one'', ''two'', ''three'']) df Out[16]: one two three 0 a 1.2 4.2 1 b 70 0.03 2 x 5 0 df.dtypes Out[17]: one object two object three object df[[''two'', ''three'']] = df[[''two'', ''three'']].astype(float) df.dtypes Out[19]: one object two float64 three float64


Aquí hay una función que toma como argumentos un DataFrame y una lista de columnas y obliga a que todos los datos de las columnas sean números.

# df is the DataFrame, and column_list is a list of columns as strings (e.g ["col1","col2","col3"]) # dependencies: pandas def coerce_df_columns_to_numeric(df, column_list): df[column_list] = df[column_list].apply(pd.to_numeric, errors=''coerce'')

Por lo tanto, para su ejemplo:

import pandas as pd def coerce_df_columns_to_numeric(df, column_list): df[column_list] = df[column_list].apply(pd.to_numeric, errors=''coerce'') a = [[''a'', ''1.2'', ''4.2''], [''b'', ''70'', ''0.03''], [''x'', ''5'', ''0'']] df = pd.DataFrame(a, columns=[''col1'',''col2'',''col3'']) coerce_df_columns_to_numeric(df, [''col2'',''col3''])


Cuando solo he necesitado especificar columnas específicas y quiero ser explícito, he usado (según astype() ):

dataframe = dataframe.astype({''col_name_1'':''int'',''col_name_2'':''float64'', etc. ...})

Entonces, usando la pregunta original, pero proporcionándole nombres de columna ...

a = [[''a'', ''1.2'', ''4.2''], [''b'', ''70'', ''0.03''], [''x'', ''5'', ''0'']] df = pd.DataFrame(a, columns=[''col_name_1'', ''col_name_2'', ''col_name_3'']) df = df.astype({''col_name_2'':''float64'', ''col_name_3'':''float64''})


Este código a continuación cambiará el tipo de datos de la columna.

df[[''col.name1'', ''col.name2''...]] = df[[''col.name1'', ''col.name2''..]].astype(''data_type'')

en lugar del tipo de datos, puede dar su tipo de datos. ¿Qué desea como str, float, int etc.?


Tienes tres opciones principales para convertir tipos en pandas.

1. to_numeric()

La mejor manera de convertir una o más columnas de un DataFrame a valores numéricos es usar pandas.to_numeric() .

Uso básico

La entrada a to_numeric() es una serie o una sola columna. Se devuelve una nueva Serie, así que recuerde asignar la salida a una variable:

# convert Series my_series = pd.to_numeric(my_series) # convert column "a" of a DataFrame df["a"] = pd.to_numeric(df["a"])

También puede usarlo para convertir varias columnas de un DataFrame a través de apply :

# convert all columns of DataFrame df = df.apply(pd.to_numeric) # convert all columns of DataFrame # convert just columns "a" and "b" df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)

Mientras sus valores se puedan convertir, eso es probablemente todo lo que necesita.

Manejo de errores

Pero, ¿qué pasa si algunos valores no se pueden convertir a un tipo numérico?

to_numeric también toma un argumento de palabra clave de errors que le permite forzar a los valores no numéricos a ser NaN , o simplemente ignorar las columnas que contienen estos valores.

Aquí hay un ejemplo utilizando una serie de cadenas s que tiene el tipo de objeto:

>>> s = pd.Series([''1'', ''2'', ''4.7'', ''pandas'', ''10'']) >>> s 0 1 1 2 2 4.7 3 pandas 4 10 dtype: object

El comportamiento predeterminado es aumentar si no puede convertir un valor. En este caso, no puede hacer frente a la cadena ''pandas'':

>>> pd.to_numeric(s) # or pd.to_numeric(s, errors=''raise'') ValueError: Unable to parse string

En lugar de fallar, podríamos querer que ''pandas'' se considere un valor numérico faltante / malo. Podemos forzar valores no válidos a NaN siguiente manera:

>>> pd.to_numeric(s, errors=''coerce'') 0 1.0 1 2.0 2 4.7 3 NaN 4 10.0 dtype: float64

La tercera opción para errors es simplemente ignorar la operación si se encuentra un valor no válido:

>>> pd.to_numeric(s, errors=''ignore'') # the original Series is returned untouched

Esta última opción es particularmente útil cuando desea convertir todo su DataFrame, pero no sabe cuál de nuestras columnas se puede convertir de manera confiable a un tipo numérico. En ese caso solo escribe:

df.apply(pd.to_numeric, errors=''ignore'')

La función se aplicará a cada columna del DataFrame. Las columnas que se pueden convertir a un tipo numérico se convertirán, mientras que las columnas que no pueden (por ejemplo, contienen cadenas o fechas sin dígitos) se dejarán solas.

Downcasting

De manera predeterminada, la conversión con to_numeric() le dará un int64 o float64 (o cualquier ancho de entero que sea nativo de su plataforma).

Eso suele ser lo que quieres, pero ¿qué sucede si quieres guardar algo de memoria y usar un tipo de letra más compacto, como float32 o int8 ?

to_numeric() te da la opción de cambiar a ''entero'', ''firmado'', ''sin firmar'', ''flotar''. Aquí hay un ejemplo para una serie simple s de tipo entero:

>>> s = pd.Series([1, 2, -7]) >>> s 0 1 1 2 2 -7 dtype: int64

La reducción a ''entero'' usa el entero más pequeño posible que puede contener los valores:

>>> pd.to_numeric(s, downcast=''integer'') 0 1 1 2 2 -7 dtype: int8

La reducción a ''flotar'' de manera similar elige un tipo flotante más pequeño que el normal:

>>> pd.to_numeric(s, downcast=''float'') 0 1.0 1 2.0 2 -7.0 dtype: float32

2. astype()

El método astype() permite ser explícito sobre el tipo de dato que desea que tenga su DataFrame o Series. Es muy versátil, ya que puedes intentar ir de un tipo a otro.

Uso básico

Simplemente elija un tipo: puede usar un tipo de tipo NumPy (por ejemplo, np.int16 ), algunos tipos de Python (por ejemplo, bool) o tipos específicos de pandas (como el tipo de código categórico).

Llame al método del objeto que desea convertir y astype() intentará convertirlo por usted:

# convert all DataFrame columns to the int64 dtype df = df.astype(int) # convert column "a" to int64 dtype and "b" to complex type df = df.astype({"a": int, "b": complex}) # convert Series to float16 type s = s.astype(np.float16) # convert Series to Python strings s = s.astype(str) # convert Series to categorical type - see docs for more details s = s.astype(''category'')

Observe que dije "intentar": si astype no sabe cómo convertir un valor en Series o DataFrame, generará un error. Por ejemplo, si tiene un valor NaN o inf , obtendrá un error al intentar convertirlo en un entero.

A partir de los pandas 0.20.0, este error se puede suprimir pasando errors=''ignore'' . Su objeto original será devuelto sin tocar.

Ten cuidado

astype() es poderoso, pero a veces convierte los valores "incorrectamente". Por ejemplo:

>>> s = pd.Series([1, 2, -7]) >>> s 0 1 1 2 2 -7 dtype: int64

Estos son enteros muy pequeños, entonces, ¿qué hay de convertir a un tipo de 8 bits sin firmar?

>>> s.astype(np.uint8) 0 1 1 2 2 249 dtype: uint8

¡La conversión funcionó, pero el -7 se redondeó para convertirse en 249 (es decir, 2 8 - 7)!

Intentar hacer un pd.to_numeric(s, downcast=''unsigned'') usando pd.to_numeric(s, downcast=''unsigned'') podría ayudar a prevenir este error.

infer_objects()

La versión 0.21.0 de pandas introdujo el método infer_objects() para convertir columnas de un DataFrame que tienen un tipo de datos de objeto a un tipo más específico (conversiones de software).

Por ejemplo, aquí se crea un DataFrame con dos columnas de tipo de objeto. Uno contiene números enteros reales y el otro contiene cadenas que representan números enteros:

>>> df = pd.DataFrame({''a'': [7, 1, 5], ''b'': [''3'',''2'',''1'']}, dtype=''object'') >>> df.dtypes a object b object dtype: object

Usando infer_objects() , puedes cambiar el tipo de columna ''a'' a int64:

>>> df = df.infer_objects() >>> df.dtypes a int64 b object dtype: object

La columna ''b'' se ha dejado sola ya que sus valores eran cadenas, no enteros. Si quisiera probar y forzar la conversión de ambas columnas a un tipo entero, podría usar df.astype(int) lugar.