web-dev-qa-db-fra.com

Python/moyen efficace de supprimer les espaces de chaque cellule du cadre de données Pandas contenant une chaîne comme un objet

Je lis un fichier CSV dans un DataFrame. J'ai besoin de supprimer les espaces de toutes les cellules ressemblant à des chaînes, en laissant les autres cellules inchangées dans Python 2.7.

Voici ce que je fais:

def remove_whitespace( x ):
    if isinstance( x, basestring ):
        return x.strip()
    else:
        return x

my_data = my_data.applymap( remove_whitespace )

Y a-t-il une meilleure façon ou plus idiomatique aux Pandas de le faire?

Existe-t-il un moyen plus efficace (peut-être en faisant les choses en termes de colonne)?

J'ai essayé de chercher une réponse définitive, mais la plupart des questions sur ce sujet semblent porter sur la suppression des espaces dans les noms de colonnes, ou sur l'hypothèse que les cellules sont toutes des chaînes.

21
deadcode

Je suis tombé sur cette question en cherchant un extrait rapide et minimaliste que je pourrais utiliser. Je devais en assembler moi-même à partir des messages ci-dessus. Peut-être que quelqu'un trouvera cela utile:

data_frame_trimmed = data_frame.apply(lambda x: x.str.strip() if x.dtype == "object" else x)
30
Adam Owczarczyk

Vous pouvez utiliser la méthode Series.str.strip() de pandas pour le faire rapidement pour chaque colonne de type chaîne:

>>> data = pd.DataFrame({'values': ['   ABC   ', '   DEF', '  GHI  ']})
>>> data
      values
0     ABC   
1        DEF
2      GHI  

>>> data['values'].str.strip()
0    ABC
1    DEF
2    GHI
Name: values, dtype: object
25
jakevdp

Lorsque vous appelez pandas.read_csv, vous pouvez utiliser une expression régulière qui correspond à zéro ou plusieurs espaces suivi d'une virgule suivie de zéro ou plusieurs espaces en tant que délimiteur.

Par exemple, voici "data.csv":

In [19]: !cat data.csv
1.5, aaa,  bbb ,  ddd     , 10 ,  XXX   
2.5, eee, fff  ,       ggg, 20 ,     YYY

(La première ligne se termine par trois espaces après XXX, tandis que la deuxième ligne se termine par la dernière Y.)

Ce qui suit utilise pandas.read_csv() pour lire les fichiers, avec l’expression régulière ' *, *' comme délimiteur. (L'utilisation d'une expression régulière comme délimiteur n'est disponible que dans le moteur "python" de read_csv().)

In [20]: import pandas as pd

In [21]: df = pd.read_csv('data.csv', header=None, delimiter=' *, *', engine='python')

In [22]: df
Out[22]: 
     0    1    2    3   4    5
0  1.5  aaa  bbb  ddd  10  XXX
1  2.5  eee  fff  ggg  20  YYY
4
Warren Weckesser

La réponse "data ['values']. Str.strip ()" ci-dessus n'a pas fonctionné pour moi, mais j'ai trouvé un moyen simple de contourner le problème. Je suis sûr qu'il existe un meilleur moyen de le faire. La fonction str.strip () fonctionne sur Series. Ainsi, j'ai converti la colonne dataframe en une série, enlevé les espaces, remplacé la colonne convertie dans le dataframe. Voici l'exemple de code. 

import pandas as pd
data = pd.DataFrame({'values': ['   ABC   ', '   DEF', '  GHI  ']})
print ('-----')
print (data)

data['values'].str.strip()
print ('-----')
print (data)

new = pd.Series([])
new = data['values'].str.strip()
data['values'] = new
print ('-----')
print (new)
3
S. Herron

J'ai trouvé le code suivant utile et quelque chose qui aiderait probablement les autres. Cet extrait de code vous permettra de supprimer des espaces dans une colonne ainsi que dans l'ensemble du DataFrame, selon votre cas d'utilisation.

import pandas as pd

def remove_whitespace(x):
    try:
        # remove spaces inside and outside of string
        x = "".join(x.split())

    except:
        pass
    return x

# Apply remove_whitespace to column only
df.orderId = df.orderId.apply(remove_whitespace)
print(df)


# Apply to remove_whitespace to entire Dataframe
df = df.applymap(remove_whitespace)
print(df)
0
FunnyChef

Cela a fonctionné pour moi - l'applique à l'ensemble du cadre de données:

def panda_strip(x):
    r =[]
    for y in x:
        if isinstance(y, str):
            y = y.strip()

        r.append(y)
    return pd.Series(r)

df = df.apply(lambda x: panda_strip(x))
0
Saul Frank

Voici une solution colonne par pandas avec:

import numpy as np

def strip_obj(col):
    if col.dtypes == object:
        return (col.astype(str)
                   .str.strip()
                   .replace({'nan': np.nan}))
    return col

df = df.apply(strip_obj, axis=0)

Cela convertira les valeurs des colonnes de type d'objet en chaîne. Devrait prendre des précautions avec les colonnes de type mixte. Par exemple, si votre colonne contient des codes postaux avec 20001 et «21110», vous obtiendrez «20001» et «21110». 

0
Blake