pandas json нормализация не работает должным образом - PullRequest
0 голосов
/ 14 июля 2020

Я использую pandas json normalize, чтобы преобразовать json в pandas фрейм данных. Это json, с которым у меня возникают проблемы:

    {
   "P48PrecTer":{
      "@xmlns":"http://sujetos.esios.ree.es/schemas/2010/05/31/P48PrecTer-esios-MP/",
      "IdSesion":"16",
      "SeriesTemporales":{
         "IdentificacionSeriesTemporales":"STP0",
         "TipoNegocio":"A10",
         "UnidadPrecio":"EUR:MWH",
         "Periodo":[
            {
               "IntervaloTiempo":"2020-07-12T00:00Z/2020-07-12T01:00Z",
               "Resolucion":"PT60M",
               "Intervalo":{
                  "Pos":"1",
                  "PrecioBaj":"25.20"
               }
            },
            {
               "IntervaloTiempo":"2020-07-12T03:00Z/2020-07-12T11:00Z",
               "Resolucion":"PT60M",
               "Intervalo":[
                  {
                     "Pos":"1",
                     "PrecioSub":"27.36"
                  },
                  {
                     "Pos":"2",
                     "PrecioBaj":"23.50"
                  },
                  {
                     "Pos":"8",
                     "PrecioBaj":"16.90"
                  }
               ]
            },
            {
               "IntervaloTiempo":"2020-07-12T12:00Z/2020-07-12T16:00Z",
               "Resolucion":"PT60M",
               "Intervalo":[
                  {
                     "Pos":"1",
                     "PrecioSub":"29.90"
                  },
                  {
                     "Pos":"4",
                     "PrecioBaj":"15.75"
                  }
               ]
            }
         ]
      }
   }
}

Я использую этот фрагмент кода:

prueba=pd.json_normalize(body,record_path=['P48PrecTer','SeriesTemporales','Periodo','Intervalo'], meta=[['P48PrecTer','IdSesion'], ['P48PrecTer','SeriesTemporales','Periodo','IntervaloTiempo']])

Я ожидаю чего-то со структурой csv. Однако я получаю следующее:

0|P48PrecTer.IdSesion|P48PrecTer.SeriesTemporales.Periodo.IntervaloTiempo
Pos|06|2020-07-12T22:00Z/2020-07-12T23:00Z
PrecioBaj|06|2020-07-12T22:00Z/2020-07-12T23:00Z
PrecioSub|06|2020-07-12T22:00Z/2020-07-12T23:00Z
{'Pos': '1', 'PrecioBaj': '4.41', 'PrecioSub': 'null'}|06|2020-07-13T00:00Z/2020-07-13T03:00Z
{'Pos': '2', 'PrecioBaj': '9.00', 'PrecioSub': 'null'}|06|2020-07-13T00:00Z/2020-07-13T03:00Z
{'Pos': '3', 'PrecioBaj': '10.10', 'PrecioSub': 'null'}|06|2020-07-13T00:00Z/2020-07-13T03:00Z

Я предполагаю, что проблема может быть в списке, связанном с ключом Periodo, поскольку я работал с другими json с аналогичной структурой и не есть проблемы. Есть ли способ добраться до цели, к которой я стремлюсь? Спасибо.

Ответы [ 2 ]

0 голосов
/ 14 июля 2020

Да, проблема в списках, представленных в dict, но мы можем решить ее следующим образом:

df = pd.json_normalize(data['P48PrecTer']['SeriesTemporales'],['Periodo'],errors='ignore')
df = df.explode('Intervalo')
df = pd.concat([df,df['Intervalo'].apply(pd.Series)],axis=1).drop(columns=[0,'Intervalo'])

for i in ['Pos','PrecioBaj']:
    df.loc[df[i].isna(),i] = df.loc[df[i].isna(),'Intervalo.'+i]
    df = df.drop(columns=['Intervalo.'+i])

print(df)

Вывод

                       IntervaloTiempo Resolucion Pos PrecioBaj PrecioSub
0  2020-07-12T00:00Z/2020-07-12T01:00Z      PT60M   1     25.20       NaN
1  2020-07-12T03:00Z/2020-07-12T11:00Z      PT60M   1       NaN     27.36
1  2020-07-12T03:00Z/2020-07-12T11:00Z      PT60M   2     23.50       NaN
1  2020-07-12T03:00Z/2020-07-12T11:00Z      PT60M   8     16.90       NaN
2  2020-07-12T12:00Z/2020-07-12T16:00Z      PT60M   1       NaN     29.90
2  2020-07-12T12:00Z/2020-07-12T16:00Z      PT60M   4     15.75       NaN
0 голосов
/ 14 июля 2020

Проблема в том, что у вас есть массив внутри массива в JSON, вы не сможете вызвать json_normalize только один раз. Он должен быть в al oop, а затем вам нужно будет объединить DataFrames, а затем объединить с внешними DataFrames.

for i in data['P48PrecTer']['SeriesTemporales']['Periodo']:
    df = pd.json_normalize(i, record_path=['Intervalo'], meta=[['IntervaloTiempo'], ['Resolucion']])
    print(df)

           0                      IntervaloTiempo Resolucion
0        Pos  2020-07-12T00:00Z/2020-07-12T01:00Z      PT60M
1  PrecioBaj  2020-07-12T00:00Z/2020-07-12T01:00Z      PT60M
  Pos PrecioSub PrecioBaj                      IntervaloTiempo Resolucion
0   1     27.36       NaN  2020-07-12T03:00Z/2020-07-12T11:00Z      PT60M
1   2       NaN     23.50  2020-07-12T03:00Z/2020-07-12T11:00Z      PT60M
2   8       NaN     16.90  2020-07-12T03:00Z/2020-07-12T11:00Z      PT60M
  Pos PrecioSub PrecioBaj                      IntervaloTiempo Resolucion
0   1     29.90       NaN  2020-07-12T12:00Z/2020-07-12T16:00Z      PT60M
1   4       NaN     15.75  2020-07-12T12:00Z/2020-07-12T16:00Z      PT60M

Лучший способ сделать это - использовать flatten_ json

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...