【问题标题】:Output an OrderedDict to CSV将 OrderedDict 输出到 CSV
【发布时间】:2015-10-15 06:52:42
【问题描述】:

我读取了一个 CSV 文件并使用 usaddress 库来解析地址字段。如何将生成的 OrderedDicts 写入另一个 CSV 文件?

import usaddress
import csv

with open('output.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        addr=row['Case Parties Address']
        data = usaddress.tag(addr)
        print(data)
(OrderedDict([('AddressNumber', u'4167'), ('StreetNamePreType', u'Highway'), ('StreetName', u'319'), ('StreetNamePostDirectional', u'E'), ('PlaceName', u'Conway'), ('StateName', u'SC'), ('ZipCode', u'29526-5446')]), 'Street Address')

【问题讨论】:

  • 读一读:gadzmo.com/python/…
  • for 循环的每一行都有一个新的标题还是一个标题一次?我在下面发布了一个假设单个标题的解决方案,但我不确定您在寻找什么......

标签: python csv


【解决方案1】:

请参阅this github issue 以获得解决方案:

import csvkit
import usaddress

# expected format in input.csv: first column 'id', second column 'address'
with open('input.csv', 'rU') as f:
    reader = csvkit.DictReader(f)

    all_rows = []
    for row in reader:
        try:
            parsed_addr = usaddress.tag(row['address'])
            row_dict = parsed_addr[0]
        except:
            row_dict = {'error':'True'}

        row_dict['id'] = row['id']
        all_rows.append(row_dict)

field_list = ['id','AddressNumber', 'AddressNumberPrefix', 'AddressNumberSuffix', 'BuildingName', 
              'CornerOf','IntersectionSeparator','LandmarkName','NotAddress','OccupancyType',
              'OccupancyIdentifier','PlaceName','Recipient','StateName','StreetName',
              'StreetNamePreDirectional','StreetNamePreModifier','StreetNamePreType',
              'StreetNamePostDirectional','StreetNamePostModifier','StreetNamePostType',
              'SubaddressIdentifier','SubaddressType','USPSBoxGroupID','USPSBoxGroupType',
              'USPSBoxID','USPSBoxType','ZipCode', 'error']

with open('output.csv', 'wb') as outfile:
    writer = csvkit.DictWriter(outfile, field_list)
    writer.writeheader()
    writer.writerows(all_rows)

一些注意事项:

  • 因为每个标记的地址可以有一组不同的键,所以您应该使用所有可能的键定义输出中的列。这不是问题,因为我们知道所有可能的 usaddress 标签
  • 如果 usaddress 标记方法无法以直观的方式连接地址标记,则会引发错误。应该在输出中捕获这些错误

【讨论】:

  • 最好在帖子中包含实际解决方案以及链接。这样就提供了解决方案,并且随着时间的推移不可避免地丢失了链接。
【解决方案2】:

在不知道 usaddress 模块的情况下,看起来 data 在这种情况下是 dict,所以当您打印 dict 时,它会打印每个 key: value 对。我猜你想在下面的解决方案中使用键作为标题,以及每行数据的值。

这是使用您发布的代码片段和一些编辑的建议。在这种情况下,您会为 for 循环的每次迭代获得一个新的标头和新的数据行,这似乎是您在没有进一步信息的情况下所要做的:

with open('output.csv') as csvfile:
reader = csv.DictReader(csvfile)

with open('myoutputfile', 'w') as o:  # this will be the new file you write to
    for row in reader:
        addr=row['Case Parties Address']
        data = usaddress.tag(addr)
        header = ','.join(data.keys()) + '\n'  # this will make a string of the header separated by comma with a newline at the end
        data_string = ','.join(data.values()) + '\n' # this will make a string of the values separated by comma with a newline at the end
        o.write(header + data_string)  # this will write the header and then the data on a new line with each field separated by commas

希望这会有所帮助。如果您尝试为 for 循环的每次迭代编写 single 标头和数据行,它看起来会有些不同...

【讨论】:

    【解决方案3】:

    以下应该有效。它假定每个地址条目都包含相同的字段。第一个条目用于自动创建标题。

    import usaddress
    import csv
    
    with open('output.csv', 'r') as f_input, open('case_parties.csv', 'wb') as f_output:
        csv_input = csv.DictReader(f_input)
        csv_output = csv.writer(f_output)
        write_headers = True
    
        for row in csv_input:
            addr=row['Case Parties Address']
            data = usaddress.tag(addr)
    
            if write_headers:
                csv_output.writerow(data[0].keys())
                write_headers = False
    
            csv_output.writerow(data[0].values())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-15
      • 2020-11-03
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2021-10-24
      相关资源
      最近更新 更多