【问题标题】:How to create a dataframe out from API result in Python如何在 Python 中从 API 结果创建数据框
【发布时间】:2019-11-26 05:34:46
【问题描述】:

我来自 Python 的Request.getcall 给了我如下输出

response.text

'{"results":[{"place":{"type":"coord","value":"44.164:28.641","lat":44.164,"lon":28.641,"tz":"Europe/Bucharest"},"measures":[{"ts":1575331200000,"date":"2019-12-03","temperature_2m":11.78,"temperature_2m_min":11.75,"temperature_2m_max":12.46,"windspeed":3.25,"direction":"SSW","wind_gust":5.43,"relative_humidity_2m":88,"sea_level_pressure":1014,"sky_cover":"cloudy","precipitation":0.0,"snow_depth":0,"thunderstorm":"N","fog":"M"}]},{"place":{"type":"coord","value":"53.546:9.98","lat":53.546,"lon":9.98,"tz":"Europe/Berlin"},"measures":[{"ts":1575331200000,"date":"2019-12-03","temperature_2m":-0.55,"temperature_2m_min":-0.8,"temperature_2m_max":-0.35,"windspeed":3.65,"direction":"WSW","wind_gust":8.62,"relative_humidity_2m":88,"sea_level_pressure":1025,"sky_cover":"mostly_clear","precipitation":0.0,"snow_depth":0,"thunderstorm":"N","fog":"M"}]}]}'

我想让数据框 df 出来

coord   date    direction   fog precipitation   relative_humidity_2m    sea_level_pressure  sky_cover   snow_depth  temperature_2m  temperature_2m_max  temperature_2m_min  thunderstorm    ts  wind_gust   windspeed
44.164:28.641   3/12/2019   SSW M                0                            88            1014        cloudy          0             11.78           12.46                  11.75              N      1.57533E+12     5.43           3.25
53.546:9.98 3/12/2019       WSW M                0                            88            1025        mostly_clear    0             -0.55           -0.35                     -0.8                    N      1.57533E+12    8.62            3.65

还有两个场景:

response.status==200 API 在response.text中给出值然后我想存储这个数据框 response.status!=200 API 没有给出任何值 response.text 然后我想将除坐标之外的所有其他字段填充为 null

如何做到这一点?

正常数据给出以下字典:

{'results': [{'place': {'type': 'coord',
    'value': '44.164:28.641',
    'lat': 44.164,
    'lon': 28.641,
    'tz': 'Europe/Bucharest'},
'measures': [{'ts': 1575331200000,
    'date': '2019-12-03',
    'temperature_2m': 11.78,
    'temperature_2m_min': 11.75,
    'temperature_2m_max': 12.46,
    'windspeed': 3.25,
    'direction': 'SSW',
    'wind_gust': 5.43,
    'relative_humidity_2m': 88,
    'sea_level_pressure': 1014,
    'sky_cover': 'cloudy',
    'precipitation': 0.0,
    'snow_depth': 0,
    'thunderstorm': 'N',
    'fog': 'M'}]},
{'place': {'type': 'coord',
    'value': '53.546:9.98',
    'lat': 53.546,
    'lon': 9.98,
    'tz': 'Europe/Berlin'},
'measures': [{'ts': 1575331200000,
    'date': '2019-12-03',
    'temperature_2m': -0.55,
    'temperature_2m_min': -0.8,
    'temperature_2m_max': -0.35,
    'windspeed': 3.65,
    'direction': 'WSW',
    'wind_gust': 8.62,
    'relative_humidity_2m': 88,
    'sea_level_pressure': 1025,
    'sky_cover': 'mostly_clear',
    'precipitation': 0.0,
    'snow_depth': 0,
    'thunderstorm': 'N',
    'fog': 'M'}]}]}

【问题讨论】:

    标签: python pandas dataframe python-requests


    【解决方案1】:
    import json
    from pandas.io.json import json_normalize
    import pandas as pd
    
    response_data = json.loads(responese.text)
    df = json_normalize(response_data['results'])
    
    df1 = json_normalize([df["measures"][i][0] for i in range(0, df.shape[0])])
    
    final_df = pd.concat([df, df1], axis=1)
    
    final_df.drop("measures", axis=1, inplace=True)
    

    【讨论】:

      【解决方案2】:

      你可以试试 DataFrame.from_records。只要“place”和“measures”中没有公共键,此解决方案就可以工作。

      import json
      
      d = json.loads(responese.text)
      
      def update(a, b):
          c = dict()
          c.update(a)
          c.update(b)
          return c
      
      
      pd.DataFrame.from_records(
          (
              update(result['place'], measure)
              for result in d['results']
              for measure in result['measures']
          )
      )
      

      结果:

          type    value   lat lon tz  ts  date    temperature_2m  temperature_2m_min  temperature_2m_max  windspeed   direction   wind_gust   relative_humidity_2m    sea_level_pressure  sky_cover   precipitation   snow_depth  thunderstorm    fog
      0   coord   44.164:28.641   44.164  28.641  Europe/Bucharest    1575331200000   2019-12-03  11.78   11.75   12.46   3.25    SSW 5.43    88  1014    cloudy  0.0 0   N   M
      1   coord   53.546:9.98 53.546  9.980   Europe/Berlin   1575331200000   2019-12-03  -0.55   -0.80   -0.35   3.65    WSW 8.62    88  1025    mostly_clear    0.0 0   N   M
      

      【讨论】:

      • response.status !=200 时,此代码是否会中断。当 API 也没有响应时,我想用 NULL 值填充数据框
      • 我认为会的。您应该检查响应状态并单独处理。我还用 json.loads 而不是 eval 更新了答案,我用它来快速计算 DF 创建。
      • 对于响应代码 !=200 ,它因以下原因而中断 response.text 'Invalid coordinates'。你知道怎么处理吗。因为我需要运行这组值
      • 对于第二种情况,如果 response.code != 200 我会做 pd.DataFrame([[np.nan] * len(columns)], columns=columns),其中 np 是 numpy 导入的因为 np 和 columns 是所需列名的列表。或者尝试 json.dumps 并对 json.JSONDecodeError 异常做出反应。
      【解决方案3】:
      d = eval(response.text)
      
      columns_needed = ['coord', 'date', 'direction', 'fog', 'precipitation',
                     'relative_humidity_2m', 'sea_level_pressure', 'sky_cover', 'snow_depth',
                     'temperature_2m', 'temperature_2m_max', 'temperature_2m_min',
                 'thunderstorm', 'ts', 'wind_gust', 'windspeed']
      
      li = []
      for i in d.get('results'):
          temp_d = dict()
          place = i.get('place')
          measure = i.get('measures')[0]
          temp_d[place.get('type')] = place.get('value')
          temp_d.update(measure)
          li.append(temp_d)
      final_df = pd.DataFrame(li)
      final_df = final_df.loc[:,columns_needed]
      
      print(final_df)
      

      【讨论】:

      • response.status !=200 时此代码是否会中断。当 API 也没有响应时,我想用 NULL 值填充数据框
      • response.status !=200 时发布示例response.text
      • response.text 'Invalid coordinates'
      • 如果 response.text 不同,您将不会在 eval(response.text) 中获得字典,最好仅在 response.status == 200 为第二种情况创建重复数据框时添加类似函数的条件 np.nan价值观
      猜你喜欢
      • 2020-05-03
      • 2016-09-09
      • 2018-03-17
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 2018-05-31
      • 2016-11-19
      • 1970-01-01
      相关资源
      最近更新 更多