sourcecode

JSON에서 Panda Data Frame으로

copyscript 2022. 9. 15. 22:49
반응형

JSON에서 Panda Data Frame으로

제가 하려는 것은 다음과 같이 위도 및 경도 좌표로 지정된 경로를 따라 Google 지도 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()

다음과 같은 데이터를 얻을 수 있습니다.

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"',
 '}']

데이터 프레임에 넣으면 다음과 같은 결과가 나옵니다.

여기에 이미지 설명 입력

pd.read_json(elevations)

내가 원하는 건 이거야

여기에 이미지 설명 입력

이것이 가능한지는 모르겠지만, 주로 판다의 데이터 프레임에 고도, 위도, 경도 데이터를 합칠 수 있는 방법을 찾고 있습니다(멋진 멀티라인 헤더를 가질 필요는 없습니다).

이 데이터를 사용하는 데 도움이 되거나 조언을 해주시면 감사하겠습니다!내가 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

최종 데이터 프레임에 위도, 경도, 표고가 있는 열

여기에 이미지 설명 입력

사용하고 싶은 것을 빠르고 간단하게 해결할 수 있는 방법을 찾았습니다.json_normalize()에 포함된.pandas 1.01.

from urllib2 import Request, urlopen
import json

import pandas as pd    

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)
df = pd.json_normalize(data['results'])

구글 지도 API에서 얻은 json 데이터로 평탄한 데이터 프레임을 얻을 수 있습니다.

이 사진을 보세요.

# 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)

도움이 되었으면 좋겠다:)

승인된 답변의 최적화:

받아들여진 답변에는 몇 가지 기능상의 문제가 있기 때문에 urlib2에 의존하지 않는 코드를 공유하고 싶습니다.

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)

출력:

        _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 

PS: API는 덴마크 전기요금용입니다.

먼저 Python 사전에 json 데이터를 Import할 수 있습니다.

data = json.loads(elevations)

그런 다음 데이터를 즉시 수정합니다.

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']

json 문자열 재구축:

elevations = json.dumps(data)

마지막으로:

pd.read_json(elevations)

데이터를 문자열로 다시 덤프하는 것을 피할 수도 있습니다.팬더라면 사전에 있는 Data Frame을 직접 만들 수 있을 것 같습니다(오랫동안 사용하지 않았습니다:p).

승인된 답변의 새로운 버전입니다.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'])

다음은 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)

Json을 사용하여 파일을 로드하고 DataFrame을 사용하여 팬더 데이터 프레임으로 변환합니다.from_from_fil 함수

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)

문제는 데이터 프레임에 작은 딕트가 포함된 여러 열이 있다는 것입니다.유용한 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')

BillmanH의 솔루션은 도움이 되었지만 다음에서 전환할 때까지 작동하지 않았습니다.

n = data.loc[row,'json_column']

대상:

n = data.iloc[[row]]['json_column']

나머지는 사전으로 변환하는 것이 json 데이터를 사용하는 데 도움이 됩니다.

import json

for row in range(len(data)):
    n = data.iloc[[row]]['json_column'].item()
    jsonDict = json.loads(n)
    if ('mykey' in jsonDict):
        display(jsonDict['mykey'])
#Use the small trick to make the data json interpret-able
#Since your data is not directly interpreted by json.loads()

>>> import json
>>> f=open("sampledata.txt","r+")
>>> data = f.read()
>>> for x in data.split("\n"):
...     strlist = "["+x+"]"
...     datalist=json.loads(strlist)
...     for y in datalist:
...             print(type(y))
...             print(y)
...
...
<type 'dict'>
{u'0': [[10.8, 36.0], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'1': [[10.8, 36.1], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'2': [[10.8, 36.2], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'3': [[10.8, 36.300000000000004], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'4': [[10.8, 36.4], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'5': [[10.8, 36.5], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'6': [[10.8, 36.6], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'7': [[10.8, 36.7], {u'10': 0, u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'8': [[10.8, 36.800000000000004], {u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}
<type 'dict'>
{u'9': [[10.8, 36.9], {u'1': 0, u'0': 0, u'3': 0, u'2': 0, u'5': 0, u'4': 0, u'7': 0, u'6': 0, u'9': 0, u'8': 0}]}


DataFrame 합격하면 '열을 '열'로 수 .MultiIndex는 다음과 같습니다. ('복수행 헤더').

df.columns = pd.MultiIndex.from_tuples([tuple(c.split('.')) for c in df.columns])

나는 사용자가 주요 '결과'를 제공하는 것을 선호하지 않는 보다 일반적인 방법을 선호한다.중첩된 데이터를 가진 키를 찾는 재귀적 접근 방식을 사용하거나, 키가 있지만 JSON이 매우 중첩된 경우에도 평탄하게 만들 수 있습니다.예를 들어 다음과 같습니다.

from pandas import json_normalize

def findnestedlist(js):
    for i in js.keys():
        if isinstance(js[i],list):
            return js[i]
    for v in js.values():
        if isinstance(v,dict):
            return check_list(v)


def recursive_lookup(k, d):
    if k in d:
        return d[k]
    for v in d.values():
        if isinstance(v, dict):
            return recursive_lookup(k, v)
    return None

def flat_json(content,key):
    nested_list = []
    js = json.loads(content)
    if key is None or key == '':
        nested_list = findnestedlist(js)
    else:
        nested_list = recursive_lookup(key, js)
    return json_normalize(nested_list,sep="_")

key = "results" # If you don't have it, give it None

csv_data = flat_json(your_json_string,root_key)
print(csv_data)

Rumble은 JSONiq에서 기본적으로 JSON을 지원하며 Spark에서 실행되어 데이터 프레임을 내부적으로 관리할 필요가 없습니다. 데이터가 완전히 구조화되지 않았더라도 다음과 같은 작업을 수행할 필요가 없습니다.

let $coords := "42.974049,-81.205203%7C42.974298,-81.195755"
let $request := json-doc("http://maps.googleapis.com/maps/api/elevation/json?locations="||$coords||"&sensor=false")
for $obj in $request.results[]
return {
  "latitude" : $obj.location.lat,
  "longitude" : $obj.location.lng,
  "elevation" : $obj.elevation
}

결과를 CSV로 내보낸 후 다른 호스트 언어로 DataFrame으로 다시 열 수 있습니다.

MongoDB 문서를 참조하면 다음 코드가 나타납니다.

from pandas import DataFrame
df = DataFrame('Your json string')

언급URL : https://stackoverflow.com/questions/21104592/json-to-pandas-dataframe

반응형