TypeError: 'Zipcode' object is not subscriptable

TypeError: 'Zipcode' object is not subscriptable

我正在使用 Python3 并且有一个 pandas df 看起来像

    zip
0   07105
1   00000
2   07030
3   07032
4   07032

我想使用 python 包 uszipcode

添加州和城市
import uszipcode
search = SearchEngine(simple_zipcode=False)
def zco(x):
    print(search.by_zipcode(x)['City'])

df['City'] = df[['zip']].fillna(0).astype(int).apply(zco)

但是,我收到以下错误

TypeError: 'Zipcode' object is not subscriptable

有人可以帮忙解决这个错误吗?提前谢谢你。

调用 search.by_zipcode(x) return 是 ZipCode() instance,而不是字典,因此对该对象应用 ['City'] 失败。

相反,使用较短别名 .city attribute.major_city 属性;你想要 return 这个值,而不是打印它:

def zco(x):
    return search.by_zipcode(x).city

如果您要使用 uszipcode 项目只是将邮政编码映射到州和城市名称,则不需要使用完整的数据库(450MB 下载)。只需保留只有 9MB 的“简单”版本,省去 SearchEngine()simple_zipcode=False 参数。

接下来,这将非常非常慢.apply() 在幕后使用一个简单的循环,对于每一行,.by_zipcode() 方法将使用 SQLAlchemy 查询 SQLite 数据库,创建一个包含匹配行中所有列的结果对象,然后 return 那个对象,这样你就可以从他们那里得到一个单一的属性。

你最好直接查询数据库,Pandas SQL methods. The uszipcode package is still useful here as it handles downloading the database for you and creating a SQLAlchemy session, the SearchEngine.ses attribute 可以让你直接访问它,但我只是从那里做:

from uszipcode import SearchEngine, SimpleZipcode

search = SearchEngine()
query = (
    search.ses.query(
        SimpleZipcode.zipcode.label('zip'),
        SimpleZipcode.major_city.label('city'),
        SimpleZipcode.state.label('state'),
    ).filter(
        SimpleZipcode.zipcode.in_(df['zip'].dropna().unique())
    )
).selectable
zipcode_df = pd.read_sql_query(query, search.ses.connection(), index_col='zip')

创建一个 Pandas 数据框,将所有唯一的邮政编码映射到城市和州列。然后你可以 join your dataframe with the zipcode dataframe:

df = pd.merge(df, zipcode_df, how='left', left_on='zip', right_index=True)

这会将 citystate 列添加到您的原始数据框中。如果您需要拉入更多列,请将它们添加到 search.ses.query(...) 部分,使用 .label() 在输出数据框中为它们提供合适的列名称(没有 .label(),它们将得到前缀为 simple_zipcode_zipcode_,具体取决于您使用的 class)。从 model attributes documented, but take into account that if you need access to the full Zipcode model attributes 中选择您需要使用 SearchEngine(simple_zipcode=False) 以确保您获得完整的 450MB 数据集,然后在查询中使用 Zipcode.<column>.label(...) 而不是 SimpleZipcode.<column>.label(...)

将邮政编码作为 zipcode_df 数据框中的索引,这将比在每一行上单独使用 SQLAlchemy 快得多(zippier :-)) .