我有一个文本数据的.tsv文件,链接在这里:
world bank data

我需要将数据读取到数据结构(任何数据结构)中,仅保留日期为“ 7/1/2000”或7/1/2010”的行,并仅保留原始19列中的7列。对编程来说是很新的东西,但是我认为这将是一个相当简单的任务,这里的代码是不完整的:

import math
import csv
import re


fhand=open("world_bank_indicators.txt", "rU")
reader=csv.reader(fhand, dialect="excel", delimiter="\t",skipinitialspace=True)

data=dict()
mylist=list()

#doesn't print headers, however
for row in reader:
    if row[1]=="7/1/2000" or row[1]=="7/1/2010":
        print row[0], row[1], row[9], row[4], row[6], row[5], row[19]


更新,使用dictreader的版本:

import math
import csv
import re

fhand=open("world_bank_indicators.txt", "rU")
reader=csv.reader(fhand, dialect="excel", delimiter="\t", lineterminator="\n")

reader=csv.DictReader(fhand, delimiter="\t")
myset=set()
mydict=dict()
mylist=list()

for row in reader:
    mydict["Date"]=row["Date"]

print mydict


但是,这似乎只给我的字典写了一个条目{date:7/1/2010}

因此,我的明显问题是:

1)这确实会打印我想要的数据的行和列,但是,它不会打印每列的标题
2)显然,什么都没有添加到任何数据结构中,以便我可以对数据进行任何计算

我在这里错过了什么(非常明显,我确定)?如何完成这两个简单的任务?

最佳答案

首先,要打印标题,您要做的就是打印出第一行的列,就像对7/1/2000行的所有列进行打印一样。例如:

headers = next(reader)
print row[0], row[1], row[9], row[4], row[6], row[5], row[19]

for row in reader:
    if row[1]=="7/1/2000" or row[1]=="7/1/2010":
        print row[0], row[1], row[9], row[4], row[6], row[5], row[19]


但是,这实际上并没有生成TSV。您只是将列分开一个空格。另外,当然,您只是将它们print放入stdout,而不是将它们写入文件。最简单的解决方案是使用csv.writer的方式与使用csv.reader的方式相同:

writer=csv.writer(outfile, dialect="excel", delimiter="\t",skipinitialspace=True)
# …
writer.writerow(row[0], row[1], row[9], row[4], row[6], row[5], row[19])


为了更简洁一点,并避免重复该列列表两次,您可能需要使用operator.itemgetter,如下所示:

columns = 0, 1, 9, 4, 6, 5, 19
getter = operator.itemgetter(*columns)
# ...
writer.writerow(getter(row))


如果要存储值而不是将其写出,只需将它们传递给append对象的list方法,而不是writerow对象的csv.writer方法。 (您可能还希望保持headers不变。)

headers = getter(next(reader))

data = []
for row in reader:
    if row[1]=="7/1/2000" or row[1]=="7/1/2010":
        data.append(getter(row))


您可以通过以下理解使其更加简洁:

data = [getter(row) for row in reader if row[1]=="7/1/2000" or row[1]=="7/1/2010"]




如果要改用DictReader,则不再按索引获取列,而按名称获取。另外,DictReader自动使用标题行来找出那些名称。这是一个简化的示例。想象一下这是您的数据:

name,email,rank
Joe,[email protected],7
Jim,[email protected],12
Jen,[email protected],2


假设我们只希望前十名中的人的电子邮件,所以这里是reader

reader = csv.reader(f)
headers = next(reader)
data = [row[1] for row in reader if int(row[2]) < 10]


这就是DictReader

reader = csv.DictReader(f)
data = [row['email'] for row in reader if int(row['rank']) < 10]


它可能不够简洁,但可能更具可读性。

10-08 09:31