JSON से पांडा डेटाफ़्रेम


143

मैं जो करने की कोशिश कर रहा हूं वह अक्षांश और देशांतर निर्देश द्वारा निर्दिष्ट पथ के साथ एक गूगल मैप्स एपीआई से ऊंचाई डेटा को निकालने के लिए है:

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

जब DataFrame के रूप में यहाँ रखा जा रहा है कि मुझे क्या मिलेगा:

यहां छवि विवरण दर्ज करें

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

कॉलम, अक्षांश, देशांतर, ऊंचाई वाले डेटाफ्रेम को समाप्त करता है

यहां छवि विवरण दर्ज करें


नमस्कार दोस्त, क्या आपको पता है कि जसन का एक टुकड़ा कैसे मिलता है? कुछ मातहत?
एम। राजकोषीय

जवाबों:


184

मैंने जो भी उपयोग करना चाहा 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'])

यह जस डेटा के साथ एक अच्छा चपटा डेटाफ़्रेम देता है जो मुझे Google मैप्स एपीआई से मिला था।


13
यह अब काम नहीं कर रहा है - मुझे pd.DataFrame.from_records()यहाँ बताए अनुसार प्रयोग करना था stackoverflow.com/a/33020669/1137803
avv

4
from_records कई बार भी काम नहीं करता है यदि json पर्याप्त रूप से जटिल है, तो आपको एक फ्लैटमैप प्राप्त करने के लिए json.io.json.json_normalize को stackoverflow.com/questions/39899005/… पर
अप्लाई करना होगा

27

इस स्निप को देखें।

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

आशा करता हूँ की ये काम करेगा :)


1
त्रुटि। आपको फ़ाइल सामग्री (यानी एक स्ट्रिंग) को json.loads () में भेजना चाहिए, न कि फ़ाइल ऑब्जेक्ट को स्वयं - json.load (train_file.read ())
Vasin Yuriy

13

आप पहले पायथन डिक्शनरी में अपना जसन डेटा आयात कर सकते हैं:

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

जसन स्ट्रिंग का पुनर्निर्माण करें:

elevations = json.dumps(data)

आखिरकार :

pd.read_json(elevations)

तुम भी, शायद एक स्ट्रिंग में डेटा वापस डंप करने से बचें, मुझे लगता है कि पांडा सीधे एक डिक्शनरी से डेटाफ़्रेम बना सकता है (मैंने इसे लंबे समय से उपयोग नहीं किया है: पी)


मैं अभी भी json डेटा और जो शब्दकोश बनाया गया था, उसी का उपयोग करके समाप्त होता है। ऐसा लगता है कि डेटाफ्रेम के प्रत्येक तत्व का अपना स्वयं का ताना-बाना है। मैंने 'डेटा' के माध्यम से पुनरावृत्ति करते हुए कम आकर्षक तरीके से लाट, लैंग और ऊंचाई के लिए एक अलग सूची बनाने में आपके दृष्टिकोण का उपयोग करने की कोशिश की।
pbreach

@ user2593236: नमस्कार, मैंने SO में अपना कोड कॉपी / पेस्ट करते समय एक त्रुटि की: एक डेल गायब था (उत्तर संपादित किया गया)
Raphaël Braud

हम्म .. अभी भी एक ही बात है जहां यह 'परिणाम' और 'स्थिति' हैडर्स के रूप में है, जबकि बाकी जोंस डेटा प्रत्येक सेल में dicts के रूप में दिखाई देते हैं। मुझे लगता है कि इस समस्या का समाधान डेटा के प्रारूप को बदलना होगा, ताकि इसे 'परिणाम' और 'स्थिति' में उप-विभाजित न किया जाए, फिर डेटा फ़्रेम में 'lat', 'lng', 'एलिवेशन', ' संकल्प 'अलग हेडर के रूप में। या तो, या मुझे एक डेटाफ्रेम में जोंस डेटा को लोड करने का एक तरीका खोजने की आवश्यकता होगी जिसमें एक बहुस्तरीय हेडर इंडेक्स होगा जैसा कि मैंने प्रश्न में उल्लेख किया है।
pbreach

आप किस अंतिम तालिका की उम्मीद करते हैं? आपके संपादन के बाद आपको जो मिला है?
राफेल ब्रूड

मेरे अंतिम संपादन के बाद मुझे जो काम मिला, मूल रूप से मुझे जो भी चाहिए था, वह था डेटा को एक सारणीबद्ध प्रारूप में प्राप्त करने के लिए जिसे मैं निर्यात कर सकता हूं और काम कर सकता हूं
pbreach

9

स्वीकृत जवाब का सिर्फ एक नया संस्करण, जैसा 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'])

4

समस्या यह है कि आपके पास डेटा फ़्रेम में कई कॉलम हैं, जिनमें उनके अंदर छोटे dicts के साथ dicts हैं। उपयोगी जसन अक्सर भारी होता है। मैं छोटे-छोटे कार्य लिख रहा हूं, जो मैं चाहता हूं कि जानकारी एक नए कॉलम में खींच लें। इस तरह से मेरे पास उस प्रारूप में है जिसका मैं उपयोग करना चाहता हूं।

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

4

स्वीकृत उत्तर का अनुकूलन:

स्वीकृत उत्तर में कुछ कामकाजी समस्याएं हैं, इसलिए मैं अपना कोड साझा करना चाहता हूं जो urllib2 पर भरोसा नहीं करता है:

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

r = requests.get(url)
dictr = r.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 

पुनश्च: एपीआई डेनिश बिजली की कीमतों के लिए है


3

यहाँ छोटा उपयोगिता वर्ग है जो 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)

1

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

1
#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}]}


1

एक बार जब आप DataFrameस्वीकार किए गए उत्तर द्वारा प्राप्त किए गए चपटा हो जाते हैं, तो आप कॉलम को MultiIndex("फैंसी मल्टीलाइन हेडर") इस तरह से बना सकते हैं:

df.columns = pd.MultiIndex.from_tuples([tuple(c.split('.')) for c in df.columns])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.