【问题标题】:Strip white spaces from CSV file从 CSV 文件中去除空格
【发布时间】:2013-01-30 21:48:59
【问题描述】:

我需要从我读取的 CSV 文件中删除空格

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)

【问题讨论】:

    标签: python csv data-munging


    【解决方案1】:

    还有嵌入的格式化参数:skipinitialspace(默认为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)
    

    【讨论】:

    • 条纹空白:reader = csv.reader(f, skipinitialspace=True,delimiter=',', quoting=csv.QUOTE_NONE),对吧?
    • 不删除尾随空格?为什么没有这个选项???
    【解决方案2】:

    就我而言,在使用csv.DictReader 时,我只关心从字段名称(又名列标题,又名字典键)中去除空格。

    基于csv.DictReader 创建一个类,并覆盖fieldnames 属性以去除每个字段名称(又名列标题,又名字典键)中的空格。

    通过获取常规的字段名称列表,然后在创建一个新列表的同时从每个字段名称中去除空格,然后对其进行迭代,并将基础_fieldnames 属性设置为这个新列表来实现此目的。

    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
    

    【讨论】:

    【解决方案3】:
    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]
    

    【讨论】:

    • 这是使用csv 模块的最佳解决方案。 csv.reader() 函数返回的 Reader 类未在 csv_csv 模块中公开以允许覆盖其 next() 方法。
    • @CivFan 生成生成器会更好,尤其是对于大文件:for row in reader: yield (c.strip() for c in row)
    【解决方案4】:

    你可以这样做:

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

    【讨论】:

      【解决方案5】:

      解析后格式化单元格的最节省内存的方法是通过generators。比如:

      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)
      

      但可能值得将其移至一个函数,您可以使用它来保持变化并避免即将进行的迭代。例如:

      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)
      

      或者它可以用来分解一个类:

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

      【讨论】:

        【解决方案6】:

        您可以在文件周围创建一个包装器对象,在 CSV 阅读器看到它们之前去除空格。这样,您甚至可以将 csv 文件与 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
        

        然后像这样使用它:

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

        我将";" 硬编码为分隔符。将代码概括为任何分隔符留给读者作为练习。

        【讨论】:

        • 将此解决方案扩展到一般情况将导致重写 csv 模块。
        【解决方案7】:

        使用 Pandas 读取 CSV(或 Excel 文件)并使用此自定义函数对其进行修剪。

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

        您现在可以像这样(作为循环的一部分等)将修剪(CSV/Excel)应用到您的代码中

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

        【讨论】:

          【解决方案8】:

          这里是适用于 Python3 的 Daniel Kullmann 出色的解决方案:

          import re
          
          class CSVSpaceStripper:
              """strip whitespaces around delimiters in the file
              NB has hardcoded delimiter ";"
              """
          
              def __init__(self, filename):
                  self.fh = open(filename, "r")
                  self.surroundingWhiteSpace = re.compile(r"\s*;\s*")
                  self.leadingOrTrailingWhiteSpace = re.compile(r"^\s*|\s*$")
          
              def close(self):
                  self.fh.close()
                  self.fh = None
          
              def __iter__(self):
                  return self
          
              def __next__(self):
                  line = self.fh.readline()
                  line = self.surroundingWhiteSpace.sub(";", line)
                  line = self.leadingOrTrailingWhiteSpace.sub("", line)
                  return line
          

          【讨论】:

            【解决方案9】:

            我想出了一个非常简单的解决方案:

            import csv
            
            with open('filename.csv') as f:
              reader = csv.DictReader(f)
              rows = [ { k.strip(): v.strip() for k,v in row.items() } for row in reader ]
            

            【讨论】:

              猜你喜欢
              • 2014-05-01
              • 2017-11-03
              • 2013-01-04
              • 2016-11-07
              • 1970-01-01
              • 1970-01-01
              • 2012-06-29
              • 2015-03-12
              相关资源
              最近更新 更多