【问题标题】:error with csv module and pygeocodercsv 模块和 pygeocoder 出错
【发布时间】:2014-03-26 04:52:21
【问题描述】:

我正在使用 pygeocoder 对地址列表进行地理编码。这是我的代码:

import csv
import pandas as pd
from pygeocoder import Geocoder
from pygeocoder import GeocoderError

df = pd.read_csv('C:\Users\L\Desktop\germanfdiaddress.csv', encoding="iso-8859-1")

address = df.Address
print address
add=[]
lat=[]
lng=[]
pcode=[]

for a in address:
    try:
        result = Geocoder.geocode(a)
        lat.extend([result[0].coordinates[0]])
        lng.extend([result[0].coordinates[1]])
        pcode.extend([result[0].postal_code])
    except GeocoderError:
        continue
    result = Geocoder.geocode(a)
    lat.extend([result[0].coordinates[0]])
    lng.extend([result[0].coordinates[1]])
    pcode.extend([result[0].postal_code])

fields= 'add','lat', 'lng', 'pcode'
rows=zip(address,lat,lng,pcode)

with open('C:\Users\L\Desktop\myfile.csv', 'wb') as outfile:
    w = csv.writer(outfile)
    w.writerow(fields)
    for i in rows:
        w.writerow(i)

但是我收到以下错误:

Traceback (most recent call last):
  File "C:\Users\Jesus\Dropbox\coding\python\geocoder with uft-8, with complete output.py", line 42, in <module>
    w.writerow(i)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 13: ordinal not in range(128)

对正在发生的事情有任何想法吗?我知道除了写入 csv 文件之外,我的代码可以正常工作。

这里是 csv 文件:https://www.dropbox.com/s/6yprg2u1ghuygye/germanfdiaddress.csv

【问题讨论】:

  • 您需要使用codecs.open并设置您要写入的文件的编码。

标签: python csv encoding geocoding


【解决方案1】:

所以我只是为 unicodecsv 更改了 csv 模块,它工作得很好。这是新代码:

import unicodecsv 
import pandas as pd 
from pygeocoder import Geocoder 
from pygeocoder import GeocoderError 

df = pd.read_csv('C:\Users\L\Desktop\germanfdiaddress.csv', encoding="iso-8859-1") 

address = df.Address 
print address 
add=[] 
lat=[] 
lng=[] 
pcode=[] 

for a in address: 
    try: 
        result = Geocoder.geocode(a) 
        lat.extend([result[0].coordinates[0]]) 
        lng.extend([result[0].coordinates[1]]) 
        pcode.extend([result[0].postal_code]) 
    except GeocoderError: 
        continue


fields= 'add','lat', 'lng', 'pcode'
rows=zip(address,lat,lng,pcode) 

with open('C:\Users\L\Desktop\myfile.csv', 'wb') as outfile: 
    w =  unicodecsv.writer(outfile, encoding='iso-8859-1') 
    w.writerow(fields) 
    for i in rows: 
        w.writerow(i)

【讨论】:

    【解决方案2】:

    csv 模块存在编码问题,而非 ASCII 有据可查:

    此版本的 csv 模块不支持 Unicode 输入。还, 目前存在一些关于 ASCII NUL 字符的问题。 因此,为了安全起见,所有输入都应该是 UTF-8 或可打印的 ASCII;

    当您进行简单的读写操作时,您可以使用documentation 中的示例UnicodeWriter 类。

    或者,您可以这样简化代码:

    import codecs
    
    # ...
    
    with codecs.open(r'C:\Users\L\Desktop\myfile.csv',
                     mode='w', encoding='utf-8') as outfile:
    
        outfile.write('{}\n'.format(','.join(fields)))
        for i in rows:
            outfile.write('{}\n'.format(','.join(i)))
    

    当您使用\ 作为路径分隔符时,请使用原始字符串r'C:\Users\L\Desktop\myfile.csv'。这是为了防止像'C:\newfile 这样的东西被错误地解释。

    您还可以使用正斜杠(即使在 Windows 中),这样就无需使用原始字符串。

    或者,您可以使用os.path.join 来构建您的文件路径。

    重点是,避免使用\

    【讨论】:

    • 感谢您的帮助。我最终使用了不同的方法,但有更多选择总是好的。
    【解决方案3】:

    为了拥有更干净的 Pythonic 外观,您可以在 GitHub 和 PyPi 上使用 Geocoder 代替 pygeocoder,同时处理 Unicode 问题 UnicodeCSV 真的很棒,您可以保持与 DictWriter 和 DictReader 相同的外观,下面是代码示例:

    import geocoder
    import unicodecsv
    import logging
    
    # CSV Writer
    csvfile = open('address_out.csv', 'wb')
    fieldnames = ['source', 'address', 'lat', 'lng', 'postal']
    writer = unicodecsv.DictWriter(csvfile, fieldnames=fieldnames, encoding='utf-8')
    writer.writeheader()
    
    # CSV Reader
    with open('address.csv', 'rb') as f:
        reader = unicodecsv.DictReader(f, encoding='iso-8859-1')
        for line in reader:
            address = line['Address']
    
            # Geocoding
            g = geocoder.google(address)
            if g.ok:
                row = {}
                row['source'] = address
                row['address'] = g.address
                row['lat'] = g.lat
                row['lng'] = g.lng
                row['postal'] = g.postal
                writer.writerow(row)
                logging.info('Geocoding SUCCESS: ' + address)
            else:
                logging.warning('Geocoding ERROR: ' + address)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      相关资源
      最近更新 更多