Strip / trim toutes les ficelles d'une dataframe
nettoyage des valeurs d'un cadre de données multitype en python/pandas, je veux couper les chaînes. Je suis actuellement en train de le faire dans les deux instructions :
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
C'est assez lent, que pourrais-je améliorer ?
6 réponses
Vous pouvez utiliser DataFrame.select_dtypes
pour sélectionner string
colonnes, puis apply
function str.strip
.
attention: les valeurs ne peuvent pas être types
dicts
ou lists
, parce que leur dtypes
object
.
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
mais s'il n'y a que quelques colonnes utilisez str.strip
:
df[0] = df[0].str.strip()
Money Shot
Voici une version compacte deapplymap
avec une simple expression lambda à appeler strip
uniquement lorsque la valeur est de type chaîne de caractères:
df.applymap(lambda x: x.strip() if type(x) is str else x)
Exemple
Un exemple plus complet:
import pandas as pd
def trimAllColumns(df):
"""
Trim whitespace from ends of each value across all series in dataframe
"""
trimStrings = lambda x: x.strip() if type(x) is str else x
return df.applymap(trimStrings)
# simple example of trimming whitespace from data elements
df = pd.DataFrame([[' a ', 10], [' c ', 5]])
df = trimAllColumns(df)
print(df)
>>>
0 1
0 a 10
1 c 5
Exemple Pratique
voici un exemple de travail hébergé par trinket: https://trinket.io/python3/65078f3cdf
si vous voulez vraiment utiliser regex, alors
>>> df.replace('(^\s+|\s+$)', '', regex=True, inplace=True)
>>> df
0 1
0 a 10
1 c 5
Mais il devrait être plus rapide à faire comme ceci:
>>> df[0] = df[0].str.strip()
Vous pouvez essayer:
df[0] = df[0].str.strip()
ou plus spécifiquement pour toutes les colonnes string
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())
Vous pouvez utiliser le apply
functionSeries
objet:
>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]])
>>> df[0][0]
' a '
>>> df[0] = df[0].apply(lambda x: x.strip())
>>> df[0][0]
'a'
notez l'utilisation de
strip
et pasregex
qui est beaucoup plus rapide
une autre option-Utilisez le apply
function de L'objet 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
def trim(x):
if x.dtype == object:
x = x.str.split(' ').str[0]
return(x)
df = df.apply(trim)