为了账号安全,请及时绑定邮箱和手机立即绑定

循环读取csv文件,每次从特定列中隔离非空元素-Python

循环读取csv文件,每次从特定列中隔离非空元素-Python

泛舟湖上清波郎朗 2022-06-14 09:49:38
我是 Python 新手,我尝试在 for 或 while 循环中顺序读取 .csv 文件(我有大约 250 个 .csv)。目的是读取每个 .csv 文件并仅隔离所有列,只要特定列(我们称其为“wanted_column”)为非空(即其非空行)。然后,将“wanted_column”的所有非空行及其所有列保存在一个新的 .csv 文件中。因此,最后,我希望拥有 250 个 .csv 文件,其中包含“wanted_column”中具有非空元素的每一行的所有列。希望这很清楚。我会很感激任何想法。乔治
查看完整描述

2 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

我在下面写了这段代码只是为了让你知道如何去做。请注意,下面的代码不会检查任何错误。如果您的 CSV 文件之一为空,如果找不到该文件,并且您定义的列是其中一个文件中的不存在列,则其行为未定义。可能还有更多。因此,您需要围绕它构建一个检查代码。此外,您的 CSV 格式可能很大程度上取决于 python csv 包。


所以现在到代码解释。对于“路径”变量。你可以给它一个字符串、一个元组或一个列表。如果您给它一个字符串,它会将其转换为具有一个索引的元组。您可以为该变量提供要使用的文件。


对于“列”变量,该变量应该是一个字符串。如果需要,您需要为此构建错误检查。


对于代码例程,该函数将读取路径列表的所有 CSV 文件。每次读取文件时,都会先读取第一行并将内容保存到变量(rowFields)中。


之后,它生成带有键(列名)到值(位置)的dict标头(字段)。该字典用于通过使用其名称来搜索列位置。在这里,您还可以浏览每个字段,如果该字段与列名匹配,则将该值保存为列位置。然后可以稍后使用该位置,而不是继续使用该名称在字典中搜索该位置。本段中描述的后一种方法应该是最快的。


之后,它会继续读取 CSV 文件的每一行,直到最后。每次读取一行时,它都会检查“column”变量定义的列中字符串的长度是否大于零。如果该字符串长度大于零,那么它将将该行附加到变量 contentRows。


函数读取完 CSV 文件后,会将变量“rowFields”和“contentRows”的内容写入由“outfile”变量定义的 CSV 文件。为了方便我,outfile 简单地等于输入文件+“.new”。你可以改变它。


import csv


def getNoneEmpty( paths, column ):

  if isinstance(paths, str):

    paths = (paths, )

  if not isinstance(paths, list) and not isinstance(paths, tuple):

    raise("paths have to be a or string, list, or tuple")


  quotechar='"'

  delimiter=","

  lineterminator="\n"


  for f in paths:

    outfile = f + ".new" # change this area to how you want to generate the new file


    fields = {}

    rowFields = None

    contentRows = []


    with open(f, newline='') as csvfile:

      csvReader = csv.reader(csvfile, delimiter=delimiter, quotechar=quotechar, lineterminator=lineterminator)


      rowFields = next(csvReader)


      for i in range(0, len(rowFields)):

        fields[rowFields[i]] = i


      for row in csvReader:

        if len(row[fields[column]]) != 0:

          contentRows.append(row)


    with open(outfile, 'w') as csvfile:

      csvWriter = csv.writer(csvfile,delimiter=delimiter, quotechar=quotechar,quoting=csv.QUOTE_MINIMAL, lineterminator=lineterminator)


      csvWriter.writerow(rowFields)

      csvWriter.writerows(contentRows)



getNoneEmpty(["test.csv","test2.csv"], "1958")

test.csv 内容:


"Month","1958","1959","1960"

"JAN",115,360,417

"FEB",318,342,391

"MAR",362,406,419

"APR",348,396,461

"MAY",11,420,472

"JUN",124,472,535

"JUL",158,548,622

"AUG",505,559,606

"SEP",404,463,508

"OCT",,407,461

"NOV",310,362,390

"DEC",110,405,432

test2.csv 内容:


"Month","1958","1959","1960"

"JAN",,360,417

"FEB",318,342,391

"MAR",362,406,419

"APR",348,396,461

"MAY",,420,472

"JUN",,472,535

"JUL",,548,622

"AUG",505,559,606

"SEP",404,463,508

"OCT",,407,461

"NOV",310,362,390

"DEC",110,405,432


查看完整回答
反对 回复 2022-06-14
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

希望它会起作用:


def main():


    temp = []

    with open(r'old_csv') as csv_file:

        csv_reader = csv.reader(csv_file, delimiter=';')


        for row in csv_reader:

            for x in row:

                temp.append(x)


    with open(r'new_csv', mode='w') as new_file:

        writer = csv.writer(new_file, delimiter=',', lineterminator='\n')


        for col in temp:

            list_ = col.split(',')

            writer.writerow(list_)


查看完整回答
反对 回复 2022-06-14
  • 2 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信