2016-08-18 1 views
0

У меня есть этот объект JSON, который имеет структуру следующим образом (объект JSON был извлечен из панд dataframe с использованием to_json(orient="records"))Python группировка JSON-объект с использованием нескольких ключей

data = [{'month': 'Jan','date': '18','activity': 'cycling','duration': 3}, 
     {'month': 'Jan', 'date': '18','activity': 'reading', 'duration': 3.0}, 
     {'month': 'Jan', 'date': '19', 'activity': 'scripting', 'duration': 19.5}, 
     {'month': 'Feb','date': '18', 'activity': 'work', 'duration': 22.0 }, 
     {'month': 'Feb', 'date': '19', 'activity': 'cooking','duration': 0.7}, 
     {'month': 'March', 'date': '16', 'activity': 'hiking', 'duration': 8.0}] 

Am пытается группы двумя полями month и date Ожидаемый результат:

data = [{ 
      "month": "Jan", 
      "details": [{ 
       "date": "18", 
       "effort": [{ 
        "activity": "cycling", 
        "duration": 3 
       }, { 
        "activity": "reading", 
        "duration": 3.0 
       }] 
      }, { 
       "date": "19", 
       "effort": [{ 
        "activity": "scripting", 
        "duration": 19.5 
       }] 
      }] 
     }, { 
      "month": "Feb", 
      "details": [{ 
       "date": "18", 
       "effort": [{ 
        "activity": "work", 
        "duration": 22.0 
       }] 
      }, { 
       "date": "19", 
       "effort": [{ 
        "activity": "cooking", 
        "duration": 0.7 
       }] 
      }] 
     }, { 
      "month": "March", 
      "details": [{ 
       "date": "16", 
       "effort": [{ 
        "activity": "hiking", 
        "duration": 8.0 
       }] 
      }] 
     }] 

Я попытался имея данные как словарь питона, который извлекается из панд dataframe использования to_dict(orient="records")

list_ = [] 

for item in dict_: 
    list_.append({"month" : item["month"], 
           "details": 
           [{ 
            "date" : item["date"], 
            "efforts" : 
             [{ 
              "activity" : item["activity"], 
              "duration": item["duration"] 
             }] 
           }] 
          }) 

json.dumps(list_)  

и выход я получил это

[{ 
    "month": "Jan", 
    "details": [{ 
     "date": "18", 
     "efforts": [{ 
      "duration": 3, 
      "activity": "cycling" 
     }] 
    }] 
}, { 
    "month": "Jan", 
    "details": [{ 
     "date": "18", 
     "efforts": [{ 
      "duration": 3.0, 
      "activity": "reading" 
     }] 
    }] 
}, { 
    "month": "Jan", 
    "details": [{ 
     "date": "19", 
     "efforts": [{ 
      "duration": 19.5, 
      "activity": "scripting" 
     }] 
    }] 
}, { 
    "month": "Feb", 
    "details": [{ 
     "date": "18", 
     "efforts": [{ 
      "duration": 22.0, 
      "activity": "work" 
     }] 
    }] 
}, { 
    "month": "Feb", 
    "details": [{ 
     "date": "19", 
     "efforts": [{ 
      "duration": 0.7, 
      "activity": "cooking" 
     }] 
    }] 
}, { 
    "month": "March", 
    "details": [{ 
     "date": "16", 
     "efforts": [{ 
      "duration": 8.0, 
      "activity": "hiking" 
     }] 
    }] 
}] 

я не обрабатывает конкатенацию значений существующих полей.

Пробовал использовать python, а также java-скрипт, есть ли у вас какие-либо советы или решения проблемы? Благодаря

+2

Пожалуйста, включите код, который вы пробовали, чтобы увидеть, в чем проблема с кодом. – Sevanteri

+0

@Sevanteri обновляет мой вопрос с помощью кода, который я пробовал. –

ответ

1

Это похоже на работу:

Code

data = [{'month': 'Jan','date': '18','activity': 'cycling','duration': 3}, 
     {'month': 'Jan', 'date': '18','activity': 'reading', 'duration': 3.0}, 
     {'month': 'Jan', 'date': '19', 'activity': 'scripting', 'duration': 19.5}, 
     {'month': 'Feb','date': '18', 'activity': 'work', 'duration': 22.0 }, 
     {'month': 'Feb', 'date': '19', 'activity': 'cooking','duration': 0.7}, 
     {'month': 'March', 'date': '16', 'activity': 'hiking', 'duration': 8.0}] 

new_data = [] 
not_found = True 
for item in data: 
    for month in new_data: 
     not_found = True 
     if item['month'] == month['month']: 
      not_found = False 
      for date in month['details']: 
       if item['date'] == date['date']: 
        date['effort'].append({'activity':item['activity'], 'duration':item['duration']}) 
       else: 
        month['details'].append({'date':item['date'], 'effort':[{'activity':item['activity'], 'duration':item['duration']}]}) 
      break 
    if not_found: 
     new_data.append({'month':item['month'], 'details':[{'date':item['date'], \ 
      'effort':[{'activity':item['activity'], 'duration':item['duration']}]}]}) 

print new_data 

Выходной

[{'details': [{'date': '18', 'effort': [{'duration': 3, 'activity': 'cycling'}, {'duration': 3.0, 'activity': 'reading'}]}, {'date': '19', 'effort': [{'duration': 19.5, 'activity': 'scripting'}, {'duration': 19.5, 'activity': 'scripting'}]}], 'month': 'Jan'}, {'details': [{'date': '18', 'effort': [{'duration': 22.0, 'activity': 'work'}]}, {'date': '19', 'effort': [{'duration': 0.7, 'activity': 'cooking'}, {'duration': 0.7, 'activity': 'cooking'}]}], 'month': 'Feb'}, {'details': [{'date': '16', 'effort': [{'duration': 8.0, 'activity': 'hiking'}]}], 'month': 'March'}] 

В основном только перебирать каждую запись, первая проверка, если месяц существует, то, если он делает, проверка если дата уже существует и соответственно добавляется к новым данным. Поэтому, если месяца нет, вы добавляете все, если нет даты, вы добавляете данные даты и новое действие. Если дата существует тоже, то вы просто добавляете активность

+0

столкнулся с другим вопросом сейчас. Ваш ответ работает в некоторых случаях и не подходит для какого-либо другого случая. Проверьте это [link] (https://ideone.com/O9dBPs). –

+0

Мой код все еще работает, вы просто изменили метод ввода. вместо использования 'json.loads (data)', используйте 'ast.literal_eval (data)' для вашей входной строки. не забудьте сделать 'import ast' – dhdavvie

Смежные вопросы