web-dev-qa-db-fra.com

Comment puis-je supprimer des espaces supplémentaires dans les chaînes lors de l'analyse d'un fichier csv dans Pandas?

J'ai le fichier suivant nommé 'data.csv':

    1997,Ford,E350
    1997, Ford , E350
    1997,Ford,E350,"Super, luxurious truck"
    1997,Ford,E350,"Super ""luxurious"" truck"
    1997,Ford,E350," Super luxurious truck "
    "1997",Ford,E350
    1997,Ford,E350
    2000,Mercury,Cougar

Et je voudrais l'analyser en un pandas DataFrame pour que le DataFrame ressemble à ceci:

       Year     Make   Model              Description
    0  1997     Ford    E350                     None
    1  1997     Ford    E350                     None
    2  1997     Ford    E350   Super, luxurious truck
    3  1997     Ford    E350  Super "luxurious" truck
    4  1997     Ford    E350    Super luxurious truck
    5  1997     Ford    E350                     None
    6  1997     Ford    E350                     None
    7  2000  Mercury  Cougar                     None

Le mieux que j'ai pu faire était:

    pd.read_table("data.csv", sep=r',', names=["Year", "Make", "Model", "Description"])

Ce qui me fait:

    Year     Make   Model              Description
 0  1997     Ford    E350                     None
 1  1997    Ford     E350                     None
 2  1997     Ford    E350   Super, luxurious truck
 3  1997     Ford    E350  Super "luxurious" truck
 4  1997     Ford    E350   Super luxurious truck 
 5  1997     Ford    E350                     None
 6  1997     Ford    E350                     None
 7  2000  Mercury  Cougar                     None

Comment puis-je obtenir le DataFrame sans ces espaces blancs?

43
mpjan

Vous pouvez utiliser des convertisseurs:

import pandas as pd

def strip(text):
    try:
        return text.strip()
    except AttributeError:
        return text

def make_int(text):
    return int(text.strip('" '))

table = pd.read_table("data.csv", sep=r',',
                      names=["Year", "Make", "Model", "Description"],
                      converters = {'Description' : strip,
                                    'Model' : strip,
                                    'Make' : strip,
                                    'Year' : make_int})
print(table)

les rendements

   Year     Make   Model              Description
0  1997     Ford    E350                     None
1  1997     Ford    E350                     None
2  1997     Ford    E350   Super, luxurious truck
3  1997     Ford    E350  Super "luxurious" truck
4  1997     Ford    E350    Super luxurious truck
5  1997     Ford    E350                     None
6  1997     Ford    E350                     None
7  2000  Mercury  Cougar                     None
47
unutbu

Eh bien, l'espace est dans vos données, vous ne pouvez donc pas lire les données sans lire dans l'espace. Cependant, après l'avoir lu, vous pouvez supprimer les espaces blancs en faisant, par exemple, df["Make"] = df["Make"].map(str.strip) (où df est votre trame de données).

26
BrenBarn

L'ajout du paramètre skipinitialspace=True À read_table a fonctionné pour moi.

Alors essayez:

pd.read_table("data.csv", 
              sep=r',', 
              names=["Year", "Make", "Model", "Description"], 
              skipinitialspace=True)

La même chose fonctionne dans pd.read_csv().

22
TheGrimmScientist

Je n'ai pas assez de réputation pour laisser un commentaire, mais la réponse ci-dessus suggérant d'utiliser la fonction map avec strip ne fonctionnera pas si vous avez des valeurs NaN, car strip ne fonctionne que sur les caractères et NaN sont des flotteurs.

Il y a une fonction intégrée pandas pour ce faire, que j'ai utilisée: pd.core.strings.str_strip(df['Description'])
df est votre trame de données. Dans mon cas, je l'ai utilisé sur une trame de données avec environ 1,2 million de lignes et c'était très rapide.

9
RKD314

Je ne pense pas que Pandas ait soutenu cela au moment où cette question a été publiée, mais la façon la plus simple de le faire est d'utiliser l'expression régulière dans le paramètre sep de read_csv. Donc, quelque chose comme ce qui suit devrait fonctionner pour ce problème.

table = pd.read_table("data.csv", sep=' *, *')
7
Hunter Jackson

La fonction str.strip () fonctionne très bien sur Series. Ainsi, je convertis la colonne de la trame de données qui contient les espaces blancs en une série, supprime l'espace blanc à l'aide de la fonction str.strip (), puis replace la colonne convertie dans la trame de données. Voici l'exemple de code.

import pandas as pd
data = pd.DataFrame({'values': ['   ABC   ', '   DEF', '  GHI  ']})
new = pd.Series([])
new = data['values'].str.strip()
data['values'] = new
2
S. Herron

Voici une fonction pour parcourir chaque colonne et appliquer pd.core.strings.str_strip:

def df_strip(df):
  df = df.copy()
  for c in df.columns:
    if df[c].dtype == np.object:
      df[c] = pd.core.strings.str_strip(df[c])
    df = df.rename(columns={c:c.strip()})
  return df
2
J Wang

read_table is Obsolète , voici le message tel qu'il apparaît dans la documentation.

Déconseillé depuis la version 0.24.0.

Utilisez pandas.read_csv () à la place, en passant sep = '\ t' si nécessaire.

Donc, en utilisant read_csv , vous pouvez passer une expression régulière pour l'argument sep, où vous pouvez spécifier le séparateur comme

sep="\s*,\s*"

n'importe quel nombre d'espaces, suivi d'un séparateur, suivi par n'importe quel nombre d'espace à nouveau , cela garantira que tous les espaces de début et de fin sont également choisis comme un bloc de délimitation qui à son tour supprime les espaces blancs de chaque côté de vos données.

regex détails comme suit:

\s -> white-space
* -> any number (zero or many)
, -> no meaning, direct character match

Ainsi, l'expression régulière \s*,\s* signifie white-space[any number] match a comma and white-space[any number].

si votre délimiteur est autre chose qu'une virgule, remplacez le , dans l'expression ci-dessus avec votre délimiteur. Par exemple: \s*;\s* si ; est votre délimiteur.

0
Rajshekar Reddy