【问题标题】:Removing rows and columns in python CSV module删除python CSV模块中的行和列
【发布时间】:2019-02-15 03:37:26
【问题描述】:

我保证在我来发这篇文章之前,我已经搜索并阅读了几页谷歌。我发誓,尽职调查已经完成。

我正在尝试在 python 中打开一个 CSV 文件,读取该文件,对其进行更改,然后写出一个新文件。

我已经走到这一步了:

import csv
def water_data ():
    with open('aquastat.csv', 'r') as csv_file:
        csv_reader = csv.reader(csv_file)
        final_file_name = "final_water.data.csv"
        final_file = open(final_file_name,'w')
        csv_writer = csv.writer(final_file,delimiter="\t")
        for row in csv_reader:
            csv_writer.writerow(row)

但我正在努力取得进一步进展。我想删除某些列,但我无法理解 python 如何知道行和列之间的区别。例如,列是Area, Area ID, Year, Value等,我只想要Area, Year, Value。我试过了

for row in final_file:

final_file.writerow(row[0] + row[2] + row[4] + row[5])

但我不断收到以下错误:IndexError: list index out of range

[我也想用*替换空白单元格,但列的东西是优先的]

请注意,我不能使用 Pandas

如果可能的话,如果有人能告诉我代码,而是向我解释一下,以便我自己进一步弄清楚,我将不胜感激。

TLDR:如何从 CVS 文件中删除空行并仅将某些列写入新文件?

输入:

"Area","Area Id","Variable Name","Variable Id","Year","Value","Symbol","Md" 
"Afghanistan",2,"Total area of the country",4100,1977,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1982,65286.0,"E","","" 
"Afghanistan",2,"Total area of the country",4100,1987,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1992,65286.0,"E","","" 
"Afghanistan",2,"Total area of the country",4100,1997,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,2002,65286.0,"E","",""

【问题讨论】:

  • 你能给我们一部分输入吗?
  • "Area","Area Id","Variable Name","Variable Id","Year","Value","Symbol","Md" "Afghanistan",2,"Total国家面积",4100,1977,65286.0,"E","","""阿富汗",2,"全国总面积",4100,1982,65286.0,"E","","" "阿富汗",2,"全国总面积",4100,1987,65286.0,"E","","""阿富汗",2,"全国总面积",4100,1992,65286.0," E","","""阿富汗",2,"全国总面积",4100,1997,65286.0,"E","","""阿富汗",2,"全国总面积" ,4100,2002,65286.0,"E","",""
  • 您能否也为输入添加您的预期输出?
  • 我不确定。我只是想清理数据。我希望数据相同,但没有区域 ID 列,或者没有空行
  • @AshleyF 你需要用 Python 来做吗?否则,您可以使用简单的 bash 命令,例如 cat File.csv | cut -d, -f1,5,6

标签: python csv


【解决方案1】:

我已尽力为您提供比您目前所做的更接近的答案。

原型:

import csv

with open('aquastat.csv', 'r') as csv_file:
  csv_reader = csv.reader(csv_file)
  final_file_name = "final_water.data.csv"
  final_file = open(final_file_name,'w')
  csv_writer = csv.writer(final_file,delimiter="\t")
  for row in csv_reader:
    if len(row) >= 6:
        row = [row[0], row[4], row[5]]
        csv_writer.writerow(row)
  final_file.close()

解释:

  • 在输出 csv 文件中的行 csv_writer.writerow(row) 之前。我添加了行row = [row[0], row[4], row[5]],其中我用一个仅包含3个单元格的数组覆盖了数组row的内容,这些单元格分别取自AreaYearValue
  • 除此之外,我还添加了一个 if 条件 if len(row) >= 6: 以检查您的行中是否至少有足够的元素来提取列直到 Value

输入:

"Area","Area Id","Variable Name","Variable Id","Year","Value","Symbol","Md"
"Afghanistan",2,"Total area of the country",4100,1977,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1982,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1987,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1992,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1997,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,2002,65286.0,"E","",""

输出:

Area    Year    Value
Afghanistan     1977    65286.0
Afghanistan     1982    65286.0
Afghanistan     1987    65286.0
Afghanistan     1992    65286.0
Afghanistan     1997    65286.0
Afghanistan     2002    65286.0

【讨论】:

    【解决方案2】:

    此行不会IndexError 并将写入忽略不存在值的行:

    final_file.writerow((row[i] for i in (0,2,5) if i<len(row)))

    此行不会IndexError 并将写入用星号替换空值的行:

    final_file.writerow((row[i] if i<len(row) else "*" for i in (0,2,5)))

    此行也不会IndexError,但不会写行:

    if len(row)>5: final_file.writerow((row[i] for i in (0,2,5)))

    此行也不会IndexError,但根本不会写任何行:

    pass

    【讨论】:

      【解决方案3】:

      您可以使用DictReader and DictWriter 选择性地修改和写入使用其标题/列名称的特定列。

      我将使用io.StringIO 来模拟文件

      s = '''"Area","Area Id","Variable Name","Variable Id","Year","Value","Symbol","Md" 
      "Afghanistan",2,"Total area of the country",4100,1977,65286.0,"E","",""
      "Afghanistan",2,"Total area of the country",4100,1982,65286.0,"E","","" 
      "Afghanistan",2,"Total area of the country",4100,1987,65286.0,"E","",""
      "Afghanistan",2,"Total area of the country",4100,1992,65286.0,"E","","" 
      "Afghanistan",2,"Total area of the country",4100,1997,65286.0,"E","",""
      "Afghanistan",2,"Total area of the country",4100,2002,65286.0,"E","",""'''
      
      f = io.StringIO(s)
      g = io.StringIO()
      
      reader = csv.DictReader(f)
      writer = csv.DictWriter(g, fieldnames=["Area","Variable Id","Value"], extrasaction='ignore')
      
      for row in reader:
          #process row values?
          row['Value'] = float(row['Value']) / 1000
          writer.writerow(row)
      

      请注意,DictWriter extrasaction 参数需要设置为'ignore',因为在原始文件中有额外的键/字段。

      如果 csv 文件没有标题行,则必须为 DictWriter 指定字段名称。


      >>> g.seek(0)
      0
      >>> print(g.read())
      Afghanistan,4100,65.286
      Afghanistan,4100,65.286
      Afghanistan,4100,65.286
      Afghanistan,4100,65.286
      Afghanistan,4100,65.286
      Afghanistan,4100,65.286
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-06
        • 2018-11-19
        • 2011-01-30
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        相关资源
        最近更新 更多