我有一个文本数据的.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]
它可能不够简洁,但可能更具可读性。