Импорт из словаря Yandex.Metrika в Pandas DataFrame

Делаю запрос данных из API Яндекс.Метрики, получаю словарь:

{'query': {'ids': [1111111], 'dimensions': ['ym:s:date', 'ym:s:firstTrafficSource'], 'metrics': ['ym:s:hits', 'ym:s:visits', 'ym:s:users'], 'sort': ['-ym:s:hits'], 'date1': '2021-01-20', 'date2': '2021-01-21', 'limit': 50000, 'offset': 1, 'group': 'day', 'auto_group_size': '1', 'attr_name': '', 'quantile': '50', 'offline_window': '21', 'attribution': 'LastSign', 'currency': 'RUB', 'adfox_event_id': '0'}, 'data': [{'dimensions': [{'name': '2021-01-20'}, {'icon_id': '3', 'icon_type': 'traffic-source', 'name': 'Ad traffic', 'id': 'ad'}], 'metrics': [139783.0, 18564.0, 14794.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '3', 'icon_type': 'traffic-source', 'name': 'Ad traffic', 'id': 'ad'}], 'metrics': [130808.0, 17650.0, 14015.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '2', 'icon_type': 'traffic-source', 'name': 'Search engine traffic', 'id': 'organic'}], 'metrics': [40899.0, 6489.0, 5621.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '2', 'icon_type': 'traffic-source', 'name': 'Search engine traffic', 'id': 'organic'}], 'metrics': [39751.0, 6299.0, 5398.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '7', 'icon_type': 'traffic-source', 'name': 'Mailing traffic', 'id': 'email'}], 'metrics': [26765.0, 2303.0, 2029.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '7', 'icon_type': 'traffic-source', 'name': 'Mailing traffic', 'id': 'email'}], 'metrics': [25877.0, 1977.0, 1734.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '0', 'icon_type': 'traffic-source', 'name': 'Direct traffic', 'id': 'direct'}], 'metrics': [20300.0, 2502.0, 2309.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '0', 'icon_type': 'traffic-source', 'name': 'Direct traffic', 'id': 'direct'}], 'metrics': [19277.0, 2125.0, 1897.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '-1', 'icon_type': 'traffic-source', 'name': 'Internal traffic', 'id': 'internal'}], 'metrics': [7113.0, 604.0, 538.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '-1', 'icon_type': 'traffic-source', 'name': 'Internal traffic', 'id': 'internal'}], 'metrics': [6988.0, 640.0, 565.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '1', 'icon_type': 'traffic-source', 'name': 'Link traffic', 'id': 'referral'}], 'metrics': [2653.0, 451.0, 416.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '1', 'icon_type': 'traffic-source', 'name': 'Link traffic', 'id': 'referral'}], 'metrics': [2305.0, 485.0, 459.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '8', 'icon_type': 'traffic-source', 'name': 'Social network traffic', 'id': 'social'}], 'metrics': [1307.0, 197.0, 194.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '8', 'icon_type': 'traffic-source', 'name': 'Social network traffic', 'id': 'social'}], 'metrics': [1103.0, 247.0, 242.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '9', 'icon_type': 'traffic-source', 'name': 'Recommendation system traffic', 'id': 'recommend'}], 'metrics': [93.0, 60.0, 60.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '4', 'icon_type': 'traffic-source', 'name': 'Cached page traffic', 'id': 'saved'}], 'metrics': [75.0, 5.0, 1.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '9', 'icon_type': 'traffic-source', 'name': 'Recommendation system traffic', 'id': 'recommend'}], 'metrics': [22.0, 18.0, 18.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': None, 'icon_type': None, 'name': None, 'id': None}], 'metrics': [14.0, 10.0, 10.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': None, 'icon_type': None, 'name': None, 'id': None}], 'metrics': [11.0, 2.0, 2.0]}, {'dimensions': [{'name': '2021-01-20'}, {'icon_id': '4', 'icon_type': 'traffic-source', 'name': 'Cached page traffic', 'id': 'saved'}], 'metrics': [4.0, 3.0, 3.0]}, {'dimensions': [{'name': '2021-01-21'}, {'icon_id': '10', 'icon_type': 'traffic-source', 'name': 'Messenger traffic', 'id': 'messenger'}], 'metrics': [2.0, 1.0, 1.0]}], 'total_rows': 21, 'total_rows_rounded': False, 'sampled': False, 'contains_sensitive_data': False, 'sample_share': 1.0, 'sample_size': 60634, 'sample_space': 60634, 'data_lag': 79, 'totals': [465150.0, 60632.0, 46928.0], 'min': [2.0, 1.0, 1.0], 'max': [139783.0, 18564.0, 14794.0]}

Далее мне надо получить 6 столбцов 'ym:s:date', 'ym:s:firstTrafficSource', 'ym:s:hits', 'ym:s:visits', 'ym:s:users' Но я могу сделать только два 'dimensions', 'metrics' с помощью:

data_out = pd.DataFrame().from_dict(data_dict['data'])

Кода пытаюсь сделать из вложенного:

data_out = pd.DataFrame().from_dict(data_dict['data']['dimensions'])

Получаю ошибку

TypeError: list indices must be integers or slices, not str

Как нужно сделать правильный импорт из словаря в DataFrame?


Ответы (1 шт):

Автор решения: strawdog

У вас в основном словаре помимо вложенных словарей есть еще и вложенные списки. Поэтому вам нужно обратиться к ключу основного словаря, затем - ко вложенному списку по индексу, а затем уже к ключам вложенного словаря. Например,:

data_dict["data"][0]["dimensions"]

выдаст вам список словарей:

[{'name': '2021-01-20'},
 {'icon_id': '3',
  'icon_type': 'traffic-source',
  'name': 'Ad traffic',
  'id': 'ad'}]
→ Ссылка