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_dtypespara seleccionarstringcolumnas y luegoapplyfuncionarstr.strip.Aviso: los valores no pueden ser
typescomodictsolists, porque sudtypesesobject.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 5Pero 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
applymapcon una expresión lambda sencilla para llamarstripsolo 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 5Ejemplo de trabajo
Aquí hay un ejemplo de trabajo alojado por trinket: https://trinket.io/python3/e6ab7fb4ab
fuente
type(x) == str, notype(x) is strisinstance(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 5Pero debería ser más rápido hacerlo así:
>>> df[0] = df[0].str.strip()fuente
Puede utilizar la
applyfunción delSeriesobjeto:>>> 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
applyfunció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 5fuente
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.