Python中使用herepy PlacesAPI嵌套字典循环构建DataFrame时重复行问题排查与解决
解决herepy PlacesAPI数据转DataFrame时重复行的问题
嘿,我看你在用herepy的PlacesAPI获取周边超市数据后,构建pandas DataFrame时遇到了重复行的问题,咱们来拆解下问题出在哪,然后搞定它!
原代码的核心问题
- 临时列表未重置:
value、address、latlong这些列表在循环外初始化,每次迭代都往里面追加数据却不清空,导致后续循环会读取到之前的旧数据,最终出现重复行。 - 固定索引取值风险高:直接用
value[0]、address[7]这种固定索引取值,一旦数据结构有变化(比如某个商家缺失houseNumber字段),就会取到错误值甚至抛出异常。 append方法效率低且已弃用:pandas的DataFrame.append()已经被标记为弃用,循环中反复调用还会导致性能低下。
优化后的解决方案
我们直接遍历返回数据里的每个商家字典,逐个提取需要的字段,把每个商家的信息整理成独立字典,最后一次性转成DataFrame,既避免重复行,又更高效健壮:
from herepy import PlacesApi import pandas as pd def dataframe(): a = {'items': [{'title': 'Marcos Francisco dos Santos Padaria e Mercearia', 'id': 'here:pds:place:07675crc-dfd72cbf57bd45cc9277ed8530ffd61b', 'ontologyId': 'here:cm:ontology:supermarket', 'resultType': 'place', 'address': {'label': 'Marcos Francisco dos Santos Padaria e Mercearia, Rua Oswero Carmo Vilaça, 33, Petrópolis - RJ, 25635-101, Brazil', 'countryCode': 'BRA', 'countryName': 'Brazil', 'stateCode': 'RJ', 'state': 'Rio de Janeiro', 'city': 'Petrópolis', 'district': 'Petrópolis', 'street': 'Rua Oswero Carmo Vilaça', 'postalCode': '25635-101', 'houseNumber': '33'}, 'position': {'lat': -22.5315, 'lng': -43.16904}, 'access': [{'lat': -22.5314, 'lng': -43.16914}], 'distance': 134, 'categories': [{'id': '600-6300-0066', 'name': 'Grocery', 'primary': True}, {'id': '600-6300-0244', 'name': 'Bakery & Baked Goods Store'}], 'contacts': [{'phone': [{'value': '+552422312493'}]}]}, {'title': 'Mr. Frango', 'id': 'here:pds:place:076jx7ps-7c214f50052f0c23c9e5422ebde7d3cd', 'ontologyId': 'here:cm:ontology:supermarket', 'resultType': 'place', 'address': {'label': 'Mr. Frango, Rua Teresa, Petrópolis - RJ, 25635-530, Brazil', 'countryCode': 'BRA', 'countryName': 'Brazil', 'stateCode': 'RJ', 'state': 'Rio de Janeiro', 'city': 'Petrópolis', 'district': 'Petrópolis', 'street': 'Rua Teresa', 'postalCode': '25635-530'}, 'position': {'lat': -22.52924, 'lng': -43.17222}, 'access': [{'lat': -22.52925, 'lng': -43.1722}], 'distance': 545, 'categories': [{'id': '600-6300-0066', 'name': 'Grocery', 'primary': True}, {'id': '600-6000-0061', 'name': 'Convenience Store'}], 'references': [{'supplier': {'id': 'core'}, 'id': '1159487213'}], 'contacts': [{'phone': [{'value': '+552422201010'}, {'value': '+552422315720', 'categories': [{'id': '600-6000-0061'}]}]}]}, {'title': 'Mercadinho Flor de Petrópolis', 'id': 'here:pds:place:07675crc-6b03dfbac65a45c0bfc52ab9a3f04556', 'ontologyId': 'here:cm:ontology:supermarket', 'resultType': 'place', 'address': {'label': 'Mercadinho Flor de Petrópolis, Rua Teresa, 2060, Petrópolis - RJ, 25635-530, Brazil', 'countryCode': 'BRA', 'countryName': 'Brazil', 'stateCode': 'RJ', 'state': 'Rio de Janeiro', 'city': 'Petrópolis', 'district': 'Petrópolis', 'street': 'Rua Teresa', 'postalCode': '25635-530', 'houseNumber': '2060'}, 'position': {'lat': -22.52895, 'lng': -43.17233}, 'access': [{'lat': -22.52895, 'lng': -43.17219}], 'distance': 574, 'categories': [{'id': '600-6300-0066', 'name': 'Grocery', 'primary': True}]}]} # 初始化列表存储每个商家的信息字典 store_records = [] # 遍历每个商家数据 for store in a['items']: # 提取地址信息,用get方法避免字段缺失报错 addr = store.get('address', {}) # 提取位置信息 pos = store.get('position', {}) # 整理当前商家的目标字段 record = { 'nome': store.get('title'), 'endereco': addr.get('label'), 'rua': addr.get('street'), 'numero': addr.get('houseNumber'), # 部分商家无门牌号时返回None 'cidade': addr.get('city'), 'estado': addr.get('state'), 'cep': addr.get('postalCode'), 'lat': pos.get('lat'), 'long': pos.get('lng'), 'raio': store.get('distance') } store_records.append(record) # 一次性转换为DataFrame,高效且无重复行 df = pd.DataFrame(store_records) return df
方案优势
- 彻底解决重复行:每次迭代仅处理当前商家的独立数据,临时变量不会累积旧数据。
- 更健壮:用
dict.get()处理字段缺失场景,即使商家没有门牌号这类字段,也不会报错。 - 性能更优:先收集所有数据到列表再转DataFrame,符合pandas最佳实践,比循环
append高效得多。
内容的提问来源于stack exchange,提问作者Mariane Santos
相关产品推荐
相关产品推荐

