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)
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)
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
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]
Tu peux faire:
aList.append([element.strip() for element in row])
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.
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))
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)))