python csv.dictreader没有使用data.gov csv

时间:2011-05-03 12:56:17

标签: python csv

使用来自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弄乱了文件....

4 个答案:

答案 0 :(得分:2)

查看我下载here的原始文件,它是有效的CSV。我误解了你脚本的输出。

由于您使用csv.DictReader,每一行都会转换为一个字典,其中标题值为键,每个数据为值。我在同一个文件上运行它,看起来所有内容都匹配正确,虽然我没有完成整个过程。

根据python docs

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: ['']是由每行数据上的尾随逗号引起的。

工作代码示例:

http://codepad.org/HdBhr4La

答案 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似乎没有道理。