使用来自data.gov的一些随机CSV数据,例如:“截至2011年1月,退伍军人和HAWAII受益人的Gravesite位置”http://www.data.gov/raw/4608我试图用python解析CSV并处理每一行:
randomData = csv.DictReader(open('/downloads/ngl_hawaii.csv', 'rb'), delimiter=",")
for row in randomData:
print row
示例CSV数据:
d_first_name,d_mid_name,d_last_name,d_suffix,d_birth_date,d_death_date,SECTION_ID,ROW_NUM,site_num,cem_name,cem_addr_one,cem_addr_two,城市,州,邮政编码,cem_url,cem_phone,关系,v_first_name,v_mid_name,v_last_name,v_suffix,树枝,秩,战争
乔, “E”, “乔乔”, “”, “1920年10月2日”, “2000年3月12日”, “100-E”, “”, “3”,“夏威夷 国家VETERANS CEMETERY“,”KAMEHAMEHA 高速公路 “ ”“, ”卡内奥赫“, ”HI“, ”111444“, ”“, ”SXXXXX“,” 退伍军人 (自我) “ ”乔“, ”E“, ”乔乔“, ”“,” 美 军队“,”SGT“,”第二次世界大战“
结果不是太漂亮(打印一行):
{'v_last_name':无,'cem_addr_two': 无,'等级':无,'d_suffix':无, 'city':无,'row_num':无,'zip': 没有,'cem_phone':没有, 'd_last_name':无,e, 'd_first_name': “乔, “E”, “乔乔”, “”, “1920年10月2日”, “2000年3月12日”, “100-E”, “”, “3”,“夏威夷 国家VETERANS CEMETERY“,”KAMEHAMEHA 高速公路 “ ”“, ”卡内奥赫“, ”HI“,” 11144 “SXXXXX”,“”,“US ARMY”,“SGT”,“世界大战” II“','war':无,'v_mid_name':无, 'cem_url':无,'cem_name':无, 'relationship':无,'v_first_name': 没有,'se one,'cem_addr_one':没有, 'd_birth_date':无,'d_death_date': 无}
如您所见,标题字段(csv中的第一行)未正确关联到每个后续行。
我做错了什么,或者CSV质量差吗?
感谢Casey询问我是否在另一个程序中打开了该文件。 Excel弄乱了文件....
答案 0 :(得分:2)
查看我下载here的原始文件,它是有效的CSV。我误解了你脚本的输出。
由于您使用csv.DictReader,每一行都会转换为一个字典,其中标题值为键,每个数据为值。我在同一个文件上运行它,看起来所有内容都匹配正确,虽然我没有完成整个过程。
class csv.DictReader(csvfile[, fieldnames=None[, restkey=None[, restval=None[, dialect='excel'[, *args, **kwds]]]]])
创建一个像普通读者一样操作的对象 但将读取的信息映射到 密钥由密钥给出的字典 可选的fieldnames参数。如果 fieldnames参数被省略了 csvfile第一行中的值 将用作字段名称。如果 行读取的字段多于 字段名序列,剩下的 数据被添加为键入的序列 restkey的值。如果行读 字段数少于字段名 序列,其余的键采取 可选restval的值 参数。任何其他可选或 关键字参数传递给 基础读者实例。
如果这不是您想要的格式,您可能需要尝试csv.reader,它只返回每行的列表而不将其与标题相关联。
要使用上面的DictReader,这可能就是你想要的:
import csv
reader = csv.DictReader(open('ngl_hawaii.csv', 'rb'), delimiter=','))
for row in reader:
print row['d_first_name']
print row['d_last_name']
答案 1 :(得分:2)
很奇怪,我得到了不同的输出。
<强> data.csv:强>
d_first_name,d_mid_name,d_last_name,d_suffix,d_birth_date,d_death_date,section_id,row_num,site_num,cem_name,cem_addr_one,cem_addr_two,city,state,zip,cem_url,cem_phone,relationship,v_first_name,v_mid_name,v_last_name,v_suffix,branch,rank,war
"Emil","E","Seibel","","10/02/1920","03/12/2010","139-E","","3","HAWAII STATE VETERANS CEMETERY","KAMEHAMEHA HIGHWAY","","KANEOHE","HI","96744","","808-233-3630","Veteran (Self)","Emil","E","Seibel","","US ARMY","SGT","WORLD WAR II",
<强>脚本:强>
for line in csv.DictReader(open('data.csv', 'rb'), delimiter=","):
print line
<强>输出:强>
{'v_last_name': 'Seibel', None: [''], 'cem_addr_two': '', 'rank': 'SGT', 'd_suffix': '', 'city': 'KANEOHE', 'row_num': '', 'zip': '96744', 'cem_phone': '808-233-3630', 'd_
last_name': 'Seibel', 'd_mid_name': 'E', 'state': 'HI', 'branch': 'US ARMY', 'd_first_name': 'Emil', 'war': 'WORLD WAR II', 'v_mid_name': 'E', 'cem_url': '', 'cem_name': '
HAWAII STATE VETERANS CEMETERY', 'relationship': 'Veteran (Self)', 'v_first_name': 'Emil', 'section_id': '139-E', 'v_suffix': '', 'site_num': '3', 'cem_addr_one': 'KAMEHAM
EHA HIGHWAY', 'd_birth_date': '10/02/1920', 'd_death_date': '03/12/2010'}
csv.DictReader
应该自动从文件的第一行获取字段名称,fieldnames
参数被省略,as described in the docs。
输出中的None: ['']
是由每行数据上的尾随逗号引起的。
工作代码示例:
答案 2 :(得分:1)
试过这个,它可以正常使用你的文件(重命名为foo)
import csv
ifile = open('foo.csv', "rb")
reader = csv.reader(ifile)
rownum = 0
for row in reader:
# Save header row.
if rownum == 0:
header = row
else:
colnum = 0
for col in row:
print '%-8s: %s' % (header[colnum], col)
colnum += 1
rownum += 1
ifile.close()
<强> OUTPUT = 强>
d_first_name: Emil
d_mid_name: E
d_last_name: Seibel
d_suffix:
d_birth_date: 10/02/1920
d_death_date: 03/12/2010
section_id: 139-E
row_num :
site_num: 3
cem_name: HAWAII STATE VETERANS CEMETERY
cem_addr_one: KAMEHAMEHA HIGHWAY
cem_addr_two:
city : KANEOHE
state : HI
zip : 96744
cem_url :
cem_phone: 808-233-3630
relationship: Veteran (Self)
v_first_name: Emil
v_mid_name: E
v_last_name: Seibel
v_suffix:
branch : US ARMY
rank : SGT
war : WORLD WAR II
答案 3 :(得分:1)
(1)报告的结果似乎已被屠杀。
据称是打印Python字典的结果,它应该能够被Python解析回字典。不是这样;这里有删除所需的Python来解析它:
d = {'v_last_name': None, 'cem_addr_two': None, 'rank': None,
'd_suffix': None, 'city': None, 'row_num': None, 'zip': None,
'cem_phone': None, 'd_last_name': None,
# e,
'd_first_name': 'Joe,"E","JoJo","","10/02/1920","03/12/2000","100-E","","3","HAWAII STATE VETERANS CEMETERY","KAMEHAMEHA HIGHWAY","","KANEOHE","HI","11144 "SXXXXX","","US ARMY","SGT","WORLD WAR II"',
'war': None, 'v_mid_name': None, 'cem_url': None, 'cem_name': None,
'relationship': None, 'v_first_name': None,
# 'se one,
'cem_addr_one': None, 'd_birth_date': None, 'd_death_date': None}
与实际数据文件的标题行相比,缺少以下列标题:
'section_id', 'v_suffix', 'd_mid_name', 'state', 'branch', 'site_num'
(2)报告的第一条数据线似乎是实际第一条数据线的编辑版本。
reported: Joe, "E","JoJo", "","10/02/1920","03/12/2000","100-E","","3","HAWAII STATE VETERANS CEMETERY","KAMEHAMEHA HIGHWAY","","KANEOHE","HI","111444","","SXXXXX", "Veteran (Self)","Joe", "E","JoJo", "","US ARMY","SGT","WORLD WAR II"
actual : "Emil","E","Seibel","","10/02/1920","03/12/2010","139-E","","3","HAWAII STATE VETERANS CEMETERY","KAMEHAMEHA HIGHWAY","","KANEOHE","HI","96744", "","808-233-3630","Veteran (Self)","Emil","E","Seibel","","US ARMY","SGT","WORLD WAR II",
changed : xxxxxx xxxxxx x xx xxxxxx xxxxxxxxxxxx xxxx xxxxxx x
如@Acorn所述,每条实际数据行末尾都有一个超级逗号。另请注意,未引用第一个报告的字段。
(3)报告的数据似乎不是用Excel打开文件,然后保存为csv的结果。
Excel在保存为csv时仅进行最小的引用,即仅在必要时引用字段。实验显示第一条数据线中没有引号。第二条数据行以US MARINE CORPS,GYSGT,"KOREA, VIETNAM"
...结尾,嵌入式逗号需要这些引号。
(4)对报告结果的进一步分析
忽略上面(1)中提到的屠宰,报告的字典有一些有趣的特征:
(a)报告的字典具有大部分预期的密钥,因此csv.DictReader设法解析标题行的结论是合理的结论。
(b)密钥d_first_name
(i)是标题行中的第一个(ii),其值是报告的第一个数据行的未分割整数。所有其他键的值都为None
。
这与使用与DictReader相同的非逗号分隔符的标题行一致,但第一个数据行使用逗号分隔符。请注意,报告的代码为delimiter=","
,这是(i)不必要的 - 它是默认值 - 和(ii)不与报告的结果一致。
结论 Blaming Excel似乎没有道理。