web-dev-qa-db-fra.com

Supprimer les espaces blancs du fichier CSV

J'ai besoin de rayer les espaces d'un fichier CSV que j'ai lu 

import csv

aList=[]
with open(self.filename, 'r') as f:
    reader = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    for row in reader:
        aList.append(row)
    # I need to strip the extra white space from each string in the row
    return(aList)
24
BAI

Il existe également le paramètre de formatage intégré: skipinitialspace (la valeur par défaut est false) http://docs.python.org/2/library/csv.html#csv-fmt-params

aList=[]
with open(self.filename, 'r') as f:
    reader = csv.reader(f, skipinitialspace=False,delimiter=',', quoting=csv.QUOTE_NONE)
    for row in reader:
        aList.append(row)
    return(aList)
33
CaraW

Dans mon cas, je me souciais seulement de supprimer les espaces blancs des noms de champs (en-têtes de colonnes, ou de clés de dictionnaire) lors de l’utilisation de csv.DictReader .

Créez une classe basée sur csv.DictReader et remplacez la propriété fieldnames pour éliminer les espaces de chaque nom de champ (en-tête de colonne ou de dictionnaire).

Pour ce faire, obtenez la liste régulière des noms de champs, puis parcourez-la en créant une nouvelle liste avec les espaces vides supprimés de chaque nom de champ et en définissant l'attribut _fieldnames sous-jacent sur cette nouvelle liste.

import csv

class DictReaderStrip(csv.DictReader):
    @property                                    
    def fieldnames(self):
        if self._fieldnames is None:
            # Initialize self._fieldnames
            # Note: DictReader is an old-style class, so can't use super()
            csv.DictReader.fieldnames.fget(self)
            if self._fieldnames is not None:
                self._fieldnames = [name.strip() for name in self._fieldnames]
        return self._fieldnames
9
CivFan
with open(self.filename, 'r') as f:
    reader = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    return [[x.strip() for x in row] for row in reader]
5
mgilson

Tu peux faire:

aList.append([element.strip() for element in row])
3
sapi

Vous pouvez créer un objet wrapper autour de votre fichier qui supprime les espaces avant que le lecteur CSV ne les voie. De cette façon, vous pouvez même utiliser le fichier csv avec cvs.DictReader.

import re

class CSVSpaceStripper:
  def __init__(self, filename):
    self.fh = open(filename, "r")
    self.surroundingWhiteSpace = re.compile("\s*;\s*")
    self.leadingOrTrailingWhiteSpace = re.compile("^\s*|\s*$")

  def close(self):
    self.fh.close()
    self.fh = None

  def __iter__(self):
    return self

  def next(self):
    line = self.fh.next()
    line = self.surroundingWhiteSpace.sub(";", line)
    line = self.leadingOrTrailingWhiteSpace.sub("", line)
    return line

Ensuite, utilisez-le comme ceci:

o = csv.reader(CSVSpaceStripper(filename), delimiter=";")
o = csv.DictReader(CSVSpaceStripper(filename), delimiter=";")

J'ai codé en dur ";" pour être le délimiteur. Généraliser le code à n’importe quel délimiteur est laissé au lecteur.

2
daniel kullmann

Lisez un fichier CSV (ou un fichier Excel) à l'aide de pandas et coupez-le à l'aide de cette fonction personnalisée.

#Definition for strippping whitespace
def trim(dataset):
    trim = lambda x: x.strip() if type(x) is str else x
    return dataset.applymap(trim)

Vous pouvez maintenant appliquer un trim (CSV/Excel) à votre code de la sorte (dans le cadre d'une boucle, etc.)

dataset = trim(pd.read_csv(dataset))
dataset = trim(pd.read_Excel(dataset))
1

La méthode la plus efficace en termes de mémoire pour formater les cellules après l'analyse est d'utiliser generators . Quelque chose comme:

with open(self.filename, 'r') as f:
    reader = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    for row in reader:
        yield (cell.strip() for cell in row)

Mais il peut être intéressant de le déplacer vers une fonction que vous pouvez utiliser pour continuer à vous évader et éviter les itérations à venir. Par exemple:

nulls = {'NULL', 'null', 'None', ''}

def clean(reader):
    def clean(row):
        for cell in row:
            cell = cell.strip()
            yield None if cell in nulls else cell

    for row in reader:
        yield clean(row)

Ou il peut être utilisé pour factoriser une classe:

def factory(reader):
    fields = next(reader)

    def clean(row):
        for cell in row:
            cell = cell.strip()
            yield None if cell in nulls else cell

    for row in reader:
        yield dict(Zip(fields, clean(row)))
1
Nuno André