【问题标题】:Why do I receive an error when I parse through a dataframe but not when it is a single row?为什么我在解析数据帧时会收到错误,但当它是单行时却没有?
【发布时间】:2019-10-12 16:22:05
【问题描述】:

python 新手。我在 python 中使用 pygeocodio 库

API_KEY = "myapikey"

from geocodio import GeocodioClient

client = GeocodioClient(API_KEY)


addresses = client.geocode("21236 Birchwood Loop, 99567, AK")
addresses.best_match.get("accuracy")
Out[61]: 1

addresses.best_match.get("accuracy_type")
Out[62]: 'rooftop'

但是,如果我想遍历数据框(example.csv):

import pandas as pd
customers = pd.read_csv("example.csv")

for row in customers.iterrows():
    addresses = client.geocode(row)
    addresses.best_match.get("accuracy")

我收到一个错误:

  File "C:\Users\jtharian\AppData\Local\Continuum\anaconda3\lib\site-packages\geocodio\client.py", line 58, in error_response
    raise exceptions.GeocodioDataError(response.json()["error"])

GeocodioDataError: Could not geocode address. Postal code or city required.

example.csv 的代表:

21236 Birchwood Loop, 99567, AK
1731 Bragaw St, 99508, AK
300 E Fireweed Ln, 99503, AK
4360 Snider Dr, 99654, AK
1921 W Dimond Blvd 108, 99515, AK
2702 Peger Rd, 99709, AK
1651 College Rd, 99709, AK
898 Ballaine Rd, 99709, AK
23819 Immelman Circle, 99567, AK
9750 W Parks Hwy, 99652, AK
7205 Shorewood Dr, 99645, AK

为什么我会收到此错误?

【问题讨论】:

  • 你的数据框只有一列吗?
  • 是的,只有一栏 @Buckeye14Guy
  • for index,row in df.iterrows(): client.geocode(row.values[0]) 还要查看数据帧的apply 方法。 iterrows 返回索引和行内容的元组。所以你没有将预期的参数传递给地理编码
  • @Buckeye14Guy 我是 python 新手。该行已运行,但我如何使用它为每一行运行addresses.best_match.get("accuracy")?

标签: python pandas geocoder


【解决方案1】:

查看api docs,您需要一个字符串来代表您的各个地址组件列中的地址,如下所示:

location = client.geocode("1109 N Highland St, Arlington VA")

因此,要在您的 df 中获得类似的列,您可以将每个向量映射到一个字符串,然后使用简单的字符串连接来生成一个字符串,然后将其插入到您的 df 中的新系列中:

import pandas as pd

customers = pd.read_csv("example.csv", header=None)
customers['address_string'] = customers[0].map(str) + ' ' + customers[1].map(str) + customers[2].map(str)

制作:

# >>> customers['address_string']
# 0       21236 Birchwood Loop 99567 AK
# 1             1731 Bragaw St 99508 AK
# 2          300 E Fireweed Ln 99503 AK
# 3             4360 Snider Dr 99654 AK
# 4     1921 W Dimond Blvd 108 99515 AK

然后您可以遍历地址字符串系列的值并将准确性存储在一个列表中,该列表可以插入您的df

geocoded_acuracy = []
geocoded_acuracy_type = []

for address in customers['address_string'].values:
    geocoded_address = client.geocode(address)
    accuracy = geocoded_address.best_match.get("accuracy")
    accuracy_type = geocoded_address.best_match.get("accuracy_type")

    geocoded_acuracy.append(accuracy)
    geocoded_acuracy_type.append(accuracy_type)

customers['accuracy'] = geocoded_acuracy
customers['accuracy_type'] = geocoded_acuracy_type

results = customers[['address_string', 'accuracy', 'accuracy_type']]

df 的结果将如下所示:

# >>> results
#                      address_string  accuracy        accuracy_type
# 0     21236 Birchwood Loop 99567 AK      1.00              rooftop
# 1           1731 Bragaw St 99508 AK      1.00              rooftop
# 2        300 E Fireweed Ln 99503 AK      1.00              rooftop
# 3           4360 Snider Dr 99654 AK      1.00  range_interpolation
# 4   1921 W Dimond Blvd 108 99515 AK      1.00              rooftop
# 5            2702 Peger Rd 99709 AK      1.00              rooftop
# 6          1651 College Rd 99709 AK      1.00              rooftop
# 7          898 Ballaine Rd 99709 AK      1.00              rooftop
# 8    23819 Immelman Circle 99567 AK      1.00              rooftop
# 9         9750 W Parks Hwy 99652 AK      0.33                place
# 10       7205 Shorewood Dr 99645 AK      1.00  range_interpolation

然后将结果df写入.csv

results.to_csv('results.csv')

将所有这些放在一起产生以下代码:

import pandas as pd
from geocodio import GeocodioClient

API_KEY = 'insert_your_key_here'

client = GeocodioClient(API_KEY)

customers = pd.read_csv("example.csv", header=None)
customers['address_string'] = customers[0].map(str) + ' ' + customers[1].map(str) + customers[2].map(str)

geocoded_acuracy = []
geocoded_acuracy_type = []

for address in customers['address_string'].values:
    geocoded_address = client.geocode(address)
    accuracy = geocoded_address.best_match.get("accuracy")
    accuracy_type = geocoded_address.best_match.get("accuracy_type")

    geocoded_acuracy.append(accuracy)
    geocoded_acuracy_type.append(accuracy_type)

customers['accuracy'] = geocoded_acuracy
customers['accuracy_type'] = geocoded_acuracy_type

results = customers[['address_string', 'accuracy', 'accuracy_type']]

results.to_csv('results.csv')

【讨论】:

  • 如何将最终输出转换为数据帧,以便写入新的 csv?另外,你能解释一下customers['address_string']语法
  • @JoelTharian 当您说最终输出时,您想要地址和准确性吗?当我查看文档时,您会得到每个地址的 json 响应并将其解析为 df 然后解析为 csv 可能是一个完全独立的问题。我添加了address_string 语法的信息
  • 但是要回答你原来的问题“为什么我会收到这个错误?”我怀疑这是为接受字符串的函数提供 pandas Series 对象的结果。
  • 我只希望准确度和准确度类型以及它们各自的地址在我的输出文件@Dodge 的 3 列中显示
  • 没关系,我已对其进行了故障排除。我只需要 customers['address_string'] = customers[0].map(str) 而不是添加另外 2 个 [1],[2] 字符串。谢谢
【解决方案2】:

我会使用apply 和特定的异常等,但现在我想虽然新的只是专注于有效的方法和错误。但是,当您熟悉 pandas 和 python 时,一定要研究这些主题。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html https://geek-university.com/python/catch-specific-exceptions/

errors, address_list, accuracy_list, accuracy_type_list = [], [], [], []
for index, row in customers.iterrows():
    try:
        addresses = client.geocode(row.values[0])
        accuracy = addresses.best_match.get("accuracy")
        accuracy_type = addresses.best_match.get("accuracy_type")

        address_list.append(addresses)
        accuracy_list.append(accuracy)
        accuracy_type_list.append(accuracy_type)
    except Exception as e:
        address_list.append(None)
        accuracy_list.append(None)
        accuracy_type_list.append(None)
        errors.append(f"failure {e.args[0]} at index {index}")

我在做什么? iterrows 提供索引和行的元组。所以我对每个行项目进行地理编码。如果它有效,我将结果添加到 address_list。与准确性相同。但是当它失败时,我会在错误列表中添加一条消息,以指示数据帧中发生错误的位置;即索引。但我还需要地址列表中的占位符,所以我只添加无。所以现在我可以做

customers['addresses'] = address_list
customers['accuracy'] = accuracy_list
customers['accuracy_type'] = accuracy_type_list

如果需要,保存我的数据框。 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html

【讨论】:

  • errors Out[73]: [ ] Errors 是一个空数据框。我正在寻找要附加到数据框的每个地址的所有准确性
  • 如果您说代码运行但错误变量是一个空列表很好。让我编辑答案
  • 我认为我没有正确解释它。那是我的坏。 @buckeye。所以基本上我正在寻找的是。对于每一行(地址),一旦您点击 api,就会显示一个准确度和准确度类型。正如我在原始帖子中给出的那样,对于 21236 Birchwood Loop、99567、AK,我收到了地址准确度 = 1 和类型 =“屋顶”。我要做的就是为我的数据框中的所有行自动执行此操作。我不想捕捉错误。我只想要每行数据的三列地址、精度、精度类型的输出文件
  • 您总是可以忽略错误列表的事情,但是在地理编码方面,我强烈建议您在地理编码方面使用某种try:...except:...。但是我提供的答案应该足以从那里开始。如果您需要准确度类型,只需对 address_list 和 accuracy_list 执行相同的操作。如果您没有捕获异常并且遇到了实际的地理编码问题,它将停止整个过程。假设一排的地址不好,如果它们都很好,我们不希望这阻止我们处理其余的。只需删除errors.append(f"failure {e.args[0]} at index {index}")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 2020-06-12
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多