Crea pandas dataframe desde objetos json.

Finalmente tengo la salida de los datos que necesito de un archivo con muchos objetos json, pero necesito ayuda para convertir la salida que se muestra a continuación en un único dataframe a medida que pasa por los datos. Aquí está el código para producir la salida que incluye una muestra de cómo se ve la salida:

datos originales:

{ "zipcode":"08989", "current"{"canwc":null,"cig":4900,"class":"observation","clds":"OVC","day_ind":"D","dewpt":19,"expireTimeGMT":1385486700,"feels_like":34,"gust":null,"hi":37,"humidex":null,"icon_code":26,"icon_extd":2600,"max_temp":37,"wxMan":"wx1111"}, "triggers":[53,31,9,21,48,7,40,178,55,179,176,26,103,175,33,51,20,57,112,30,50,113] } { "zipcode":"08990", "current":{"canwc":null,"cig":4900,"class":"observation","clds":"OVC","day_ind":"D","dewpt":19,"expireTimeGMT":1385486700,"feels_like":34,"gust":null,"hi":37,"humidex":null,"icon_code":26,"icon_extd":2600,"max_temp":37, "wxMan":"wx1111"}, "triggers":[53,31,9,21,48,7,40,178,55,179,176,26,103,175,33,51,20,57,112,30,50,113] } def lines_per_n(f, n): for line in f: yield ''.join(chain([line], itertools.islice(f, n - 1))) for fin in glob.glob('*.txt'): with open(fin) as f: for chunk in lines_per_n(f, 5): try: jfile = json.loads(chunk) zipcode = jfile['zipcode'] datetime = jfile['current']['proc_time'] triggers = jfile['triggers'] print pd.Series(jfile['zipcode']), pd.Series(jfile['current']['proc_time']),\ jfile['triggers'] except ValueError, e: pass else: pass 

Ejemplo de salida que obtengo cuando ejecuto lo anterior, que me gustaría almacenar en un dataframe de pandas como 3 columnas.

 08988 20131126102946 [] 08989 20131126102946 [53, 31, 9, 21, 48, 7, 40, 178, 55, 179] 08988 20131126102946 [] 08989 20131126102946 [53, 31, 9, 21, 48, 7, 40, 178, 55, 179] 00544 20131126102946 [178, 30, 176, 103, 179, 112, 21, 20, 48] 

Por lo tanto, el código que aparece a continuación parece estar mucho más cerca, ya que me da un df funky si paso el de la lista y Transpose el df. ¿Alguna idea de cómo puedo obtener esta remodelación correctamente?

 def series_chunk(chunk): jfile = json.loads(chunk) zipcode = jfile['zipcode'] datetime = jfile['current']['proc_time'] triggers = jfile['triggers'] return jfile['zipcode'],\ jfile['current']['proc_time'],\ jfile['triggers'] for fin in glob.glob('*.txt'): with open(fin) as f: for chunk in lines_per_n(f, 7): df1 = pd.DataFrame(list(series_chunk(chunk))) print df1.T [u'08988', u'20131126102946', []] [u'08989', u'20131126102946', [53, 31, 9, 21, 48, 7, 40, 178, 55, 179]] [u'08988', u'20131126102946', []] [u'08989', u'20131126102946', [53, 31, 9, 21, 48, 7, 40, 178, 55, 179]] 

Marco de datos:

  0 1 2 0 08988 20131126102946 [] 0 1 2 0 08989 20131126102946 [53, 31, 9, 21, 48, 7, 40, 178, 55, 179, 176, ... 0 1 2 0 08988 20131126102946 [] 0 1 2 0 08989 20131126102946 [53, 31, 9, 21, 48, 7, 40, 178, 55, 179, 176, ... 

Aquí está mi código final y salida. ¿Cómo capturo cada dataframe que crea a través del bucle y los concateno sobre la marcha como un objeto de dataframe?

 for fin in glob.glob('*.txt'): with open(fin) as f: print pd.concat([series_chunk(chunk) for chunk in lines_per_n(f, 7)], axis=1).T 0 1 2 0 08988 20131126102946 [] 1 08989 20131126102946 [53, 31, 9, 21, 48, 7, 40, 178, 55, 179, 176, ... 0 1 2 0 08988 20131126102946 [] 1 08989 20131126102946 [53, 31, 9, 21, 48, 7, 40, 178, 55, 179, 176, ... 

Nota: para aquellos de ustedes que llegan a esta pregunta que buscan analizar json en pandas, si tienen un json válido (esta pregunta no), deben usar la función pandas read_json :

 # can either pass string of the json, or a filepath to a file with valid json In [99]: pd.read_json('[{"A": 1, "B": 2}, {"A": 3, "B": 4}]') Out[99]: AB 0 1 2 1 3 4 

Echa un vistazo a la parte IO de los documentos para ver varios ejemplos, argumentos que puedes pasar a esta función, así como formas de normalizar json menos estructurados.

Si no tiene json válido , a menudo es eficiente mezclar la cadena antes de leer como json, por ejemplo, vea esta respuesta .

Si tiene varios archivos json, debe reunir los DataFrames juntos (similar a en esta respuesta):

 pd.concat([pd.read_json(file) for file in ...], ignore_index=True) 

Respuesta original para este ejemplo:

Use una mirada detrás de la expresión regular para el separador pasado a read_csv:

 In [11]: df = pd.read_csv('foo.csv', sep='(? 

Como se mencionó en los comentarios, puede hacer esto más directamente concat varias Series juntas ... También será un poco más fácil de seguir:

 def series_chunk(chunk): jfile = json.loads(chunk) zipcode = jfile['zipcode'] datetime = jfile['current']['proc_time'] triggers = jfile['triggers'] return pd.Series([jfile['zipcode'], jfile['current']['proc_time'], jfile['triggers']]) dfs = [] for fin in glob.glob('*.txt'): with open(fin) as f: df = pd.concat([series_chunk(chunk) for chunk in lines_per_n(f, 5)], axis=1) dfs.append(dfs) df = pd.concat(dfs, ignore_index=True) 

Nota: También puede mover el try / except a series_chunk .