Limpiando los valores de un marco de datos de varios tipos en python / pandas, quiero recortar las cadenas. Actualmente lo estoy haciendo en dos instrucciones:
import pandas as pd
df = pd.DataFrame([[' a ', 10], [' c ', 5]])
df.replace('^\s+', '', regex=True, inplace=True) #front
df.replace('\s+$', '', regex=True, inplace=True) #end
df.values
Esto es bastante lento, ¿qué podría mejorar?
df.replace(r'\s*(.*?)\s*', r'\1', regex=True)
Respuestas:
Puede utilizar
DataFrame.select_dtypes
para seleccionarstring
columnas y luegoapply
funcionarstr.strip
.Aviso: los valores no pueden ser
types
comodicts
olists
, porque sudtypes
esobject
.df_obj = df.select_dtypes(['object']) print (df_obj) 0 a 1 c df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip()) print (df) 0 1 0 a 10 1 c 5
Pero si solo hay unas pocas columnas, use
str.strip
:df[0] = df[0].str.strip()
fuente
Tiro de dinero
Aquí hay una versión compacta del uso
applymap
con una expresión lambda sencilla para llamarstrip
solo cuando el valor es de un tipo de cadena:df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
Ejemplo completo
Un ejemplo más completo:
import pandas as pd def trim_all_columns(df): """ Trim whitespace from ends of each value across all series in dataframe """ trim_strings = lambda x: x.strip() if isinstance(x, str) else x return df.applymap(trim_strings) # simple example of trimming whitespace from data elements df = pd.DataFrame([[' a ', 10], [' c ', 5]]) df = trim_all_columns(df) print(df) >>> 0 1 0 a 10 1 c 5
Ejemplo de trabajo
Aquí hay un ejemplo de trabajo alojado por trinket: https://trinket.io/python3/e6ab7fb4ab
fuente
type(x) == str
, notype(x) is str
isinstance(x, str)
.Puedes probar:
df[0] = df[0].str.strip()
o más específicamente para todas las columnas de cadena
non_numeric_columns = list(set(df.columns)-set(df._get_numeric_data().columns)) df[non_numeric_columns] = df[non_numeric_columns].apply(lambda x : str(x).strip())
fuente
Si realmente quieres usar expresiones regulares, entonces
>>> df.replace('(^\s+|\s+$)', '', regex=True, inplace=True) >>> df 0 1 0 a 10 1 c 5
Pero debería ser más rápido hacerlo así:
>>> df[0] = df[0].str.strip()
fuente
Puede utilizar la
apply
función delSeries
objeto:>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]]) >>> df[0][0] ' a ' >>> df[0] = df[0].apply(lambda x: x.strip()) >>> df[0][0] 'a'
Otra opción: use la
apply
función del objeto DataFrame:>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]]) >>> df.apply(lambda x: x.apply(lambda y: y.strip() if type(y) == type('') else y), axis=0) 0 1 0 a 10 1 c 5
fuente
df[0] = df[0].str.strip()
- probablemente será más rápido en DF más grandesdef trim(x): if x.dtype == object: x = x.str.split(' ').str[0] return(x) df = df.apply(trim)
fuente
가나다 봻
parte izquierda del espacio en blanco es lo que quiero, la parte derecha es basura. La función de recorte extrae lo que quiero de los datos sin procesar.