JSON到pandas DataFrame

pbr*_*ach 112 python json google-maps pandas

我想要做的是沿着纬度和经度坐标指定的路径从谷歌地图API中提取高程数据,如下所示:

from urllib2 import Request, urlopen
import json

path1 = '42.974049,-81.205203|42.974298,-81.195755'
request=Request('http://maps.googleapis.com/maps/api/elevation/json?locations='+path1+'&sensor=false')
response = urlopen(request)
elevations = response.read()
Run Code Online (Sandbox Code Playgroud)

这给了我一个如下所示的数据:

elevations.splitlines()

['{',
 '   "results" : [',
 '      {',
 '         "elevation" : 243.3462677001953,',
 '         "location" : {',
 '            "lat" : 42.974049,',
 '            "lng" : -81.205203',
 '         },',
 '         "resolution" : 19.08790397644043',
 '      },',
 '      {',
 '         "elevation" : 244.1318664550781,',
 '         "location" : {',
 '            "lat" : 42.974298,',
 '            "lng" : -81.19575500000001',
 '         },',
 '         "resolution" : 19.08790397644043',
 '      }',
 '   ],',
 '   "status" : "OK"',
 '}']
Run Code Online (Sandbox Code Playgroud)

当我在这里投入DataFrame时,我得到的是:

在此输入图像描述

pd.read_json(elevations)
Run Code Online (Sandbox Code Playgroud)

这就是我想要的:

在此输入图像描述

我不确定这是否可行,但主要是我正在寻找的是一种能够将高程,纬度和经度数据放在一个pandas数据帧中的方法(不必有花哨的多线头).

如果任何人可以帮助或提供一些关于使用这些数据的建议,这将是很棒的!如果你不能告诉我之前我没有用过json数据...

编辑:

这种方法并不是那么有吸引力,但似乎有效:

data = json.loads(elevations)
lat,lng,el = [],[],[]
for result in data['results']:
    lat.append(result[u'location'][u'lat'])
    lng.append(result[u'location'][u'lng'])
    el.append(result[u'elevation'])
df = pd.DataFrame([lat,lng,el]).T
Run Code Online (Sandbox Code Playgroud)

最终数据框具有列纬度,经度,高程

在此输入图像描述

pbr*_*ach 157

我使用最新版本的pandas 0.13中包含的json_normalize函数找到了一个快速简单的解决方案.

from urllib2 import Request, urlopen
import json
from pandas.io.json import json_normalize

path1 = '42.974049,-81.205203|42.974298,-81.195755'
request=Request('http://maps.googleapis.com/maps/api/elevation/json?locations='+path1+'&sensor=false')
response = urlopen(request)
elevations = response.read()
data = json.loads(elevations)
json_normalize(data['results'])
Run Code Online (Sandbox Code Playgroud)

这给出了一个很好的扁平数据框,其中包含我从google maps API获得的json数据.

  • 这似乎不再起作用 - 我必须使用`pd.DataFrame.from_records()`,如此处所述http://stackoverflow.com/a/33020669/1137803 (9认同)
  • 如果json足够复杂,from_records有时也不起作用,您必须应用json.io.json.json_normalize来获得平面图。请查看/sf/ask/2792930381/一个带有一些列的熊猫数据帧作为json / 39906235 (2认同)

Ris*_*shu 21

检查这个剪辑.

# reading the JSON data using json.load()
file = 'data.json'
with open(file) as train_file:
    dict_train = json.load(train_file)

# converting json dataset from dictionary to dataframe
train = pd.DataFrame.from_dict(dict_train, orient='index')
train.reset_index(level=0, inplace=True)
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你 :)


Dis*_*ale 21

已接受答案的优化:

接受的答案有一些功能问题,所以我想分享我不依赖 urllib2 的代码:

import requests
from pandas import json_normalize
url = 'https://www.energidataservice.dk/proxy/api/datastore_search?resource_id=nordpoolmarket&limit=5'

response = requests.get(url)
dictr = response.json()
recs = dictr['result']['records']
df = json_normalize(recs)
print(df)
Run Code Online (Sandbox Code Playgroud)

输出:

        _id                    HourUTC               HourDK  ... ElbasAveragePriceEUR  ElbasMaxPriceEUR  ElbasMinPriceEUR
0    264028  2019-01-01T00:00:00+00:00  2019-01-01T01:00:00  ...                  NaN               NaN               NaN
1    138428  2017-09-03T15:00:00+00:00  2017-09-03T17:00:00  ...                33.28              33.4              32.0
2    138429  2017-09-03T16:00:00+00:00  2017-09-03T18:00:00  ...                35.20              35.7              34.9
3    138430  2017-09-03T17:00:00+00:00  2017-09-03T19:00:00  ...                37.50              37.8              37.3
4    138431  2017-09-03T18:00:00+00:00  2017-09-03T20:00:00  ...                39.65              42.9              35.3
..      ...                        ...                  ...  ...                  ...               ...               ...
995  139290  2017-10-09T13:00:00+00:00  2017-10-09T15:00:00  ...                38.40              38.4              38.4
996  139291  2017-10-09T14:00:00+00:00  2017-10-09T16:00:00  ...                41.90              44.3              33.9
997  139292  2017-10-09T15:00:00+00:00  2017-10-09T17:00:00  ...                46.26              49.5              41.4
998  139293  2017-10-09T16:00:00+00:00  2017-10-09T18:00:00  ...                56.22              58.5              49.1
999  139294  2017-10-09T17:00:00+00:00  2017-10-09T19:00:00  ...                56.71              65.4              42.2 
Run Code Online (Sandbox Code Playgroud)

PS:API 是针对丹麦电价的

  • 这个解决方案更好,因为你可以只关注“pandas”包而不导入其他包 (2认同)

小智 12

使用 Json 加载文件并使用 DataFrame.from_dict 函数将其转换为 pandas 数据帧

import json
import pandas as pd
json_string = '{ "name":"John", "age":30, "car":"None" }'

a_json = json.loads(json_string)
print(a_json)

dataframe = pd.DataFrame.from_dict(a_json)
Run Code Online (Sandbox Code Playgroud)


Rap*_*aud 11

您可以先在Python字典中导入json数据:

data = json.loads(elevations)
Run Code Online (Sandbox Code Playgroud)

然后即时修改数据:

for result in data['results']:
    result[u'lat']=result[u'location'][u'lat']
    result[u'lng']=result[u'location'][u'lng']
    del result[u'location']
Run Code Online (Sandbox Code Playgroud)

重建json字符串:

elevations = json.dumps(data)
Run Code Online (Sandbox Code Playgroud)

最后:

pd.read_json(elevations)
Run Code Online (Sandbox Code Playgroud)

您也可以避免将数据转储回字符串,我假设Panda可以直接从字典中创建一个DataFrame(我很久没有使用它了:p)


AB *_*bhi 7

只是接受答案的新版本,因为python3.x不支持urllib2

from requests import request
import json
from pandas.io.json import json_normalize

path1 = '42.974049,-81.205203|42.974298,-81.195755'
response=request(url='http://maps.googleapis.com/maps/api/elevation/json?locations='+path1+'&sensor=false', method='get')
elevations = response.json()
elevations
data = json.loads(elevations)
json_normalize(data['results'])
Run Code Online (Sandbox Code Playgroud)


小智 7

这是将 JSON 转换为 DataFrame 并返回的小型实用程序类:希望您觉得这有帮助。

# -*- coding: utf-8 -*-
from pandas.io.json import json_normalize

class DFConverter:

    #Converts the input JSON to a DataFrame
    def convertToDF(self,dfJSON):
        return(json_normalize(dfJSON))

    #Converts the input DataFrame to JSON 
    def convertToJSON(self, df):
        resultJSON = df.to_json(orient='records')
        return(resultJSON)
Run Code Online (Sandbox Code Playgroud)


bil*_*anH 5

问题是数据框中有几列包含其中包含较小字典的字典。有用的 Json 通常是大量嵌套的。我一直在编写一些小函数,将我想要的信息提取到一个新列中。这样我就有了我想要使用的格式。

for row in range(len(data)):
    #First I load the dict (one at a time)
    n = data.loc[row,'dict_column']
    #Now I make a new column that pulls out the data that I want.
    data.loc[row,'new_column'] = n.get('key')
Run Code Online (Sandbox Code Playgroud)