【问题标题】:Python- Modifying a csv filePython - 修改 csv 文件
【发布时间】:2017-11-07 06:31:57
【问题描述】:

现在我知道在读取 csv 文件时修改它通常是不可行的,因此您需要创建一个新的 csv 文件并写入它。我遇到的问题是保留数据的原始顺序。

输入的 csv 文件如下所示:

C1       C2         C3
apple    BANANA     Mango
pear     PineApple  StRaWbeRRy

我想将所有数据转成小写并输出一个新的 csv 文件,如下所示:

C1       C2         C3
apple    banana     mango
pear     pineapple  strawberry

到目前为止,我可以遍历输入 csv 文件并将所有值转换为小写,但我不知道如何将其重写为该格式的 csv 文件。我的代码是:

def clean (input)
  aList = []
  file = open(input, "r")
  reader = csv.reader(file, delimiter = ',')
  next(reader, None) # Skip the header but I want to preserve it in the output csv file
  for row in reader:
     for col in row:
        aList.append(col.lower())

所以现在我有一个包含所有小写数据的列表,如何将其重写为与输入格式相同(行数和列数相同)的 csv 文件,包括我在代码中跳过的标题行.

【问题讨论】:

  • 不要费心将行保存到列表中。只需同时打开您的输入和输出文件,这样您就可以在创建时编写每个修改的行。事实上,我什至不会为此使用csv 模块。很遗憾您需要保留标题行的大小写,否则您可以使用 tr 程序处理整个文件(如果您使用的是类 Unix 操作系统)。
  • 与熊猫:pd.read_csv(input).apply(str.lower).to_csv(input)
  • 我刚刚注意到您的代码将, 指定为分隔符,但您的示例数据使用空格。请解释!
  • @PM2Ring 如果您使用 head 命令抓取标题,您仍然可以使用命令行工具。
  • @PM2Ring 我只是在这里以这种方式表示数据。输入位于包含这些行和列的 csv 文件中。话虽如此,我也不知道为什么 delimiter ,但它确实有效!最初是个错误,但效果很好

标签: python csv


【解决方案1】:

如果您只想更改数据的大小写并保留其他所有内容,您最好跳过 csv 模块并使用 直接文件 例如:

# Open both files
with open("infile.csv") as f_in, open("outfile.csv", 'w') as f_out:
    # Write header unchanged
    header = f_in.readline()
    f_out.write(header)

    # Transform the rest of the lines
    for line in f_in:
        f_out.write(line.lower())

【讨论】:

    【解决方案2】:

    熊猫方式:

    使用pandas 读取文件并获取数据框。然后你可以简单地使用lower()

    import pandas as pd
    
    def conversion(text):
        return text.lower()
        
    
    df = pd.read_csv(file_path)
    df[column_name] = df[column_name].map(conversion)
    

    甚至是一个班轮:

    df[column_name] = df[column_name].apply(lambda x: x.lower()) # If you have nan or other non-string values, you may need to convert x to string first like str(x).lower()
    

    然后你可以使用to_csv函数保存它

    【讨论】:

      【解决方案3】:

      如果你想全部使用 csv 模块,请使用以下代码 sn-p。

      import os
      import csv
      
      
      def clean(input):
          tmpFile = "tmp.csv"
          with open(input, "r") as file, open(tmpFile, "w") as outFile:
              reader = csv.reader(file, delimiter=',')
              writer = csv.writer(outFile, delimiter=',')
              header = next(reader)
              writer.writerow(header)
              for row in reader:
                  colValues = []
                  for col in row:
                      colValues.append(col.lower())
                  writer.writerow(colValues)
          os.rename(tmpFile, input)
      

      【讨论】:

      • 没错,那么我们需要再创建一个文件,最后复制该文件。
      • 您应该修复空白缩进。您在不同的点使用 1、2、3 和 4 个空格。 Python 不会喜欢这样的!
      • @Tim 我正在使用有问题的 ideone。我已经使用 PyCharm 解决了这个问题。
      【解决方案4】:

      我发现的最简单的方法如下 让最初的CSV文件名是test.csv

      with open('test.csv','r') as f:
          with open('cleaned.csv','w') as ff:
              ff.write(f.readline())
              ff.write(f.read().lower())
      

      以上代码将创建一个全小写的新 csv

      【讨论】:

      • 好的,现在可以正常工作了。但就像您的早期版本一样,它不必要地将整个文件读入字符串。另外,正如 Tim 所提到的,它使用更多的 RAM 来进行字符串连接。但我想这可能没问题,除非文件很大,并且一次更改整个文件的大小写 比逐行更改更有效。
      • 您希望避免字符串连接。如果这是一个大文件,您将不得不为整个文件分配足够的内存,然后再次连接标题。
      • 所以,我应该直接将其写入文件而不是连接? @蒂姆
      • @user8898218 是的。字符串在 python 中是不可变的,因此连接会导致一个新的 str 被实例化,并且被连接的两个字符串的内容被复制进来。
      猜你喜欢
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 1970-01-01
      相关资源
      最近更新 更多