2017-09-25 1 views
0

J'ai une URL qui renvoie les données JSON comme suit:json.loads python pour pandas géants dataframe

{ 
    u 'fields': [{ 
      u 'keyField': False, 
      u 'name': u '_blockid', 
      u 'fieldType': u 'long' 
     }, { 
      u 'keyField': False, 
      u 'name': u '_collector', 
      u 'fieldType': u 'string' 
     }, { 
      u 'keyField': False, 
      u 'name': u '_collectorid', 
      u 'fieldType': u 'long' 
     }, { 
      u 'keyField': False, 
      u 'name': u '_messageid', 
      u 'fieldType': u 'long' 
     } 
    ], 
    u 'messages': [{ 
      u 'map': { 
       u '_messageid': u '-9223368783568280026', 
       u '_collectorid': u '135927517', 
       u '_blockid': u '-9223372036519990555', 
       u '_collector': u 'collector1', 
      } 
     }, { 
      u 'map': { 
       u '_messageid': u '-92233645345280026', 
       u '_collectorid': u '13545342517', 
       u '_blockid': u '-92234254242343219990555', 
       u '_collector': u 'collector2', 
      } 
     } 
    ] 
} 

C'est un extrait. Le vrai JSON contient des milliers de valeurs sous [ 'messages'] [ 'map']

j'ai un script qui fonctionne comme suit

rJSON = requests.get(JsonURL, auth=(username, password)) 
DATA = json.loads(rJSON.text) 
for x in DATA[u'messages']: 
    print type(x[u'map']) 
    for i in x[u'map']: 
     print np.isscalar(x[u'map'][i]) 

    df = pd.DataFrame.from_dict(x[u'map']) 
    break ### TESTING ### 

Cette affiche le

<type 'dict'> 
True 
True 
True 
True 
True 
True 
True 
True 
True 
True 
True 
True 
True 
True 
True 

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-151-1b71c28d4d83> in <module>() 
    11  for i in x[u'map']: 
    12   print np.isscalar(q[i]) 
---> 13  df = pd.DataFrame.from_dict(x[u'map']) 
    14 
    15  #if isinstance(msgData, pd.DataFrame): # If the variable is a dataframe, append to it... 

C:\Users\USERID\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\frame.pyc in from_dict(cls, data, orient, dtype) 
    849    raise ValueError('only recognize index or columns for orient') 
    850 
--> 851   return cls(data, index=index, columns=columns, dtype=dtype) 
    852 
    853  def to_dict(self, orient='dict'): 

C:\Users\USERID\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\frame.pyc in __init__(self, data, index, columns, dtype, copy) 
    273         dtype=dtype, copy=copy) 
    274   elif isinstance(data, dict): 
--> 275    mgr = self._init_dict(data, index, columns, dtype=dtype) 
    276   elif isinstance(data, ma.MaskedArray): 
    277    import numpy.ma.mrecords as mrecords 

C:\Users\USERID\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\frame.pyc in _init_dict(self, data, index, columns, dtype) 
    409    arrays = [data[k] for k in keys] 
    410 
--> 411   return _arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype) 
    412 
    413  def _init_ndarray(self, values, index, columns, dtype=None, copy=False): 

C:\Users\USERID\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\frame.pyc in _arrays_to_mgr(arrays, arr_names, index, columns, dtype) 
    5494  # figure out the index, if necessary 
    5495  if index is None: 
-> 5496   index = extract_index(arrays) 
    5497  else: 
    5498   index = _ensure_index(index) 

C:\Users\USERID\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\frame.pyc in extract_index(data) 
    5533 
    5534   if not indexes and not raw_lengths: 
-> 5535    raise ValueError('If using all scalar values, you must pass' 
    5536        ' an index') 
    5537 

ValueError: If using all scalar values, you must pass an index 

suivant, je comprends c'est fou parce que le dictionnaire contient des valeurs scalaires, mais je n'arrive pas à comprendre pourquoi elles sont chargées dans le dictionnaire par json.loads() en tant que scalaire, ou comment les convertir de scalaire en chaînes.

Mon but final est de prendre toutes les données ['messages'] ['map'] et pd.concat les dans la boucle dans 1 grande dataframe que je peux analyser.

Est-il possible d'empêcher json.loads de les charger en tant que scalaires? Ou existe-t-il un moyen de les convertir de scalaires en quelque chose d'autre qui peut être chargé dans un cadre de données?

+0

Essayez le 'orient = paramètre 'index''? – ako

Répondre

0

Les messages dans les données est une liste de dictionnaires, vous pouvez le charger avec DataFrame.from_records puis utiliser apply(pd.Series) pour convertir les dictionnaires internes aux lignes de la trame de données finale:

pd.DataFrame.from_records(data['messages']).map.apply(pd.Series) 

#     _blockid _collector _collectorid   _messageid 
#0  -9223372036519990555 collector1 135927517 -9223368783568280026 
#1 -92234254242343219990555 collector2 13545342517 -92233645345280026 
+1

Merci! C'est ce que j'ai fait! – user3246693