python csv data-munging

python - Eliminar espacios en blanco del archivo CSV



data-munging (7)

Necesito separar los espacios en blanco de un archivo CSV que leí

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)


El método más eficiente en memoria para formatear las celdas después del análisis es a través de generators . Algo como:

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)

Pero puede valer la pena pasarlo a una función que pueda usar para mantenerse al margen y evitar futuras iteraciones. Por ejemplo:

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)

O se puede usar para factorizar una clase:

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)))


En mi caso, solo me importaba eliminar los espacios en blanco de los nombres de los campos (también conocidos como encabezados de columna, también conocidas como claves del diccionario), cuando utilizaba csv.DictReader .

Cree una clase basada en csv.DictReader , y anule la propiedad de fieldnames para eliminar el espacio en blanco de cada nombre de campo (también conocido como encabezado de columna, clave de diccionario).

Haga esto obteniendo la lista regular de nombres de campo, y luego itérelo mientras crea una nueva lista con el espacio en blanco eliminado de cada nombre de campo, y establezca el atributo _fieldnames subyacente en esta nueva lista.

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


Lea un archivo CSV (o archivo Excel) con Pandas y recórtelo con esta función personalizada.

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

Ahora puede aplicar recorte (CSV / Excel) a su código así (como parte de un bucle, etc.)

dataset = trim(pd.read_csv(dataset)) dataset = trim(pd.read_excel(dataset))


Puede crear un objeto envoltorio alrededor de su archivo que elimine los espacios antes de que el lector CSV los vea. De esta manera, incluso puede utilizar el archivo csv con 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

Entonces úsalo así:

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

He codificado ";" para ser el delimitador. La generalización del código a cualquier delimitador se deja como un ejercicio para el lector.


También está el parámetro de formato incorporado: skipinitialspace (el valor predeterminado es falso) 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)


Tu puedes hacer:

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


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]