【问题标题】:Is there a way to unnest a json´column in a dataframe?有没有办法在数据框中取消嵌套 json´column?
【发布时间】:2022-01-06 07:26:30
【问题描述】:

我有这个数据集

obras = pd.DataFrame(
    [['1','Entre Ríos'],['2', 'Entre Rios'],['3','entre Ríos'], ['4','Entre ríos']],
    columns = ['id', 'prov']
)

为了规范“Prov”的名称,我调用了一个 API

API_BASE_URL = "https://apis.datos.gob.ar/georef/api/"

def get_similar_bulk(endpoint, nombres):

    # realiza consulta a la API
    data = {
        endpoint: [
            {"nombre": nombre, "max": 1} for nombre in nombres
    ]}
    url = API_BASE_URL + endpoint
    results = requests.post(
        url, json=data, headers={"Content-Type": "application/json"}
    ).json()

    # convierte a una lista de "resultado más probable" o "vacío" cuando no hay
    parsed_results = [
        single_result[endpoint][0] if single_result[endpoint] else {}
        for single_result in results["resultados"]
    ]

    return parsed_results

obras['prov_norm'] = get_similar_bulk("provincias", obras['prov'])

结果我得到了

id prov prov_norm
1 Entre Ríos {'centroide': {'lat': -32.0588735436448, 'lon': -59.2014475514635}, 'id': '30', 'nombre': 'Entre Ríos'}
2 Entre Rios {'centroide': {'lat': -32.0588735436448, 'lon': -59.2014475514635}, 'id': '30', 'nombre': 'Entre Ríos'}
3 entre Ríos {'centroide': {'lat': -32.0588735436448, 'lon': -59.2014475514635}, 'id': '30', 'nombre': 'Entre Ríos'}
4 Entre ríos {'centroide': {'lat': -32.0588735436448, 'lon': -59.2014475514635}, 'id': '30', 'nombre': 'Entre Ríos'}

预期的结果是:

id prov lat lon id nombre
1 Entre Ríos -32.0588735436448 -59.2014475514635 30 Entre Ríos
2 Entre Rios -32.0588735436448 -59.2014475514635 30 Entre Ríos
3 entre Ríos -32.0588735436448 -59.2014475514635 30 Entre Ríos
4 Entre ríos -32.0588735436448 -59.2014475514635 30 Entre Ríos

我该如何解决这个问题?

谢谢!!!

【问题讨论】:

    标签: python json dataframe


    【解决方案1】:

    您也可以尝试如下所示的 pandas 'json_normalize':

    import pandas as pd
    
    results = get_similar_bulk("provincias", obras['prov'])
    
    df_results = pd.json_normalize(results)
    
    print(df_results)
    

    【讨论】:

    • 最好的选择,确实:) +1
    【解决方案2】:

    如果你想要单独的列,那么你必须像这样将数据放在单独的列中:

    在 get_similar_bulk 函数中:

    # convierte a una lista de "resultado más probable" o "vacío" cuando no hay
      parsed_results = [
          single_result[endpoint][0] if single_result[endpoint] else {}
          for single_result in results["resultados"]
      ]
    
      parsed_results = [{'lat':x['centroide']['lat'],'lon': x['centroide']['lon'],'id_obras': x['id'],'nombre':x['nombre']} for x in parsed_results ]
      parsed_results=[[x[0] for x in parsed_results],[x[1] for x in parsed_results],[x[2] for x in parsed_results],[x[3] for x in parsed_results]]
    
      return parsed_results
    
    obras['lat'],obras['lon'],obras['id'],obras['nombre'] = 
     get_similar_bulk("provincias", obras['prov'])
    
    

    但如果我们在您的代码之后更改数据:

    obras['lat'] = obras['prov_norm'].apply(lambda x:  x['centroide']['lat'])
    obras['lon'] = obras['prov_norm'].apply(lambda x:  x['centroide']['lon'])
    obras['id_obras'] = obras['prov_norm'].apply(lambda x:  x['id'])
    obras['nombre'] = obras['prov_norm'].apply(lambda x:  x['nombre'])
    
    
    obras = obras.drop('prov_norm', 1)
    
    

    但我不明白为什么所有行的数据都相同。这也是你问题的一部分吗?还是只是一个示例代码?

    【讨论】:

    • 感谢您的回答。我需要规范化省名并获取 de lon lat 数据。问题是在我运行规范化 API 之后,你得到一个 json 列,我必须取消嵌套里面的数据。
    • 这是您问题的答案吗?如果没有,请分享更多有助于解决问题的详细信息。我编辑了答案的第一部分。 @Facundo Javier Vargas
    猜你喜欢
    • 1970-01-01
    • 2019-08-30
    • 2017-01-09
    • 2019-03-16
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多