Доступ к массиву, который находится в списке, который является значением в словаре? - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть большой вложенный словарь, который содержит некоторые данные временных рядов, моя цель - извлечь эти данные временных рядов. Я могу выполнять некоторые базовые навигационные операции по словарю, но все эти разные типы данных действительно меня отталкивают. Вот MWE с вложенным словарем, который содержит данные о времени и времени и данные об осадках с 2 разных сайтов мониторинга. В конце концов, я хотел бы построить их вместе с любым количеством сайтов мониторинга.

Здесь я делаю все возможное, чтобы получить данные из словаря в массив numpy, а затем в pandas массив данных. Однако вы увидите, что в кадре данных имеется по одной строке на станцию ​​и один столбец, в котором содержится массив осадков каждой станции. Я ожидал, что он покажет такое же количество столбцов, что и значения данных. Это лучший способ достичь моей цели? Если да, то как мне изменить количество столбцов?

import numpy as np
import pandas as pd

no_stations = 2
my_dict = {
    "UNITS":{
        "precipitation":"Inches"
        },
        "STATION": [
            {'STATUS': 'ACTIVE',
             'NAME' : 'STATION 1',
             'ELEVATION': '758',
             'OBSERVATIONS': {'date_time': [
                '2020-04-13T13:00:00Z', '2020-04-13T14:00:00Z', '2020-04-13T15:00:00Z',
                '2020-04-13T16:00:00Z', '2020-04-13T17:00:00Z', '2020-04-13T18:00:00Z',
                '2020-04-13T19:00:00Z', '2020-04-13T20:00:00Z', '2020-04-13T21:00:00Z',
                '2020-04-13T22:00:00Z', '2020-04-13T23:00:00Z', '2020-04-14T00:00:00Z',
                '2020-04-14T01:00:00Z', '2020-04-14T02:00:00Z', '2020-04-14T03:00:00Z',
                '2020-04-14T04:00:00Z', '2020-04-14T05:00:00Z', '2020-04-14T06:00:00Z',
                '2020-04-14T07:00:00Z', '2020-04-14T08:00:00Z', '2020-04-14T09:00:00Z',
                '2020-04-14T10:00:00Z', '2020-04-14T11:00:00Z', '2020-04-14T12:00:00Z',
                '2020-04-14T13:00:00Z', '2020-04-14T14:00:00Z', '2020-04-14T15:00:00Z',
                '2020-04-14T16:00:00Z', '2020-04-14T17:00:00Z', '2020-04-14T18:00:00Z'],
            'precip_accum_set_1': [
                 0.0, 0.0, 0.0, 0.254, 1.27, 2.794, 4.064, 5.588, 6.858, 8.89, 10.922,
                 12.192, 12.954, 13.716, 15.24, 18.034, 18.288, 18.288, 18.288, 20.32,
                 22.606, 24.892, 25.908, 26.924, 27.432, 27.686, 27.686,
                 27.686, 27.686, 27.94]}},
            {'STATUS': 'ACTIVE',
             'NAME' : 'STATION 2',
             'ELEVATION': '500',
             'OBSERVATIONS': {'date_time': [
                '2020-04-13T13:00:00Z', '2020-04-13T14:00:00Z', '2020-04-13T15:00:00Z',
                '2020-04-13T16:00:00Z', '2020-04-13T17:00:00Z', '2020-04-13T18:00:00Z',
                '2020-04-13T19:00:00Z', '2020-04-13T20:00:00Z', '2020-04-13T21:00:00Z',
                '2020-04-13T22:00:00Z', '2020-04-13T23:00:00Z', '2020-04-14T00:00:00Z',
                '2020-04-14T01:00:00Z', '2020-04-14T02:00:00Z', '2020-04-14T03:00:00Z',
                 '2020-04-14T04:00:00Z', '2020-04-14T05:00:00Z', '2020-04-14T06:00:00Z',
                '2020-04-14T07:00:00Z', '2020-04-14T08:00:00Z', '2020-04-14T09:00:00Z',
                '2020-04-14T10:00:00Z', '2020-04-14T11:00:00Z', '2020-04-14T12:00:00Z',
                '2020-04-14T13:00:00Z', '2020-04-14T14:00:00Z', '2020-04-14T15:00:00Z',
                '2020-04-14T16:00:00Z', '2020-04-14T17:00:00Z', '2020-04-14T18:00:00Z'],
            'precip_accum_set_1': [
                49.53, 49.53, 49.53, 50.038, 51.054, 52.324,53.594, 54.864, 56.134,
                59.944, 61.214, 61.722,62.484, 64.008, 66.802, 67.056, 67.056, 67.31,
                69.088, 71.628, 74.168, 75.184, 75.946, 76.454,76.708,
                76.708, 76.708, 76.708, 76.708]}}
                ]
            }


for key, value in my_dict.items():
    print(key)
    print(type(value))

precip = np.empty([no_stations], dtype=object)
dates = np.empty([no_stations], dtype=object)

for ii in range(no_stations):
    precip[ii] = my_dict['STATION'][ii]['OBSERVATIONS']['precip_accum_set_1']
    dates[ii] = my_dict['STATION'][ii]['OBSERVATIONS']['date_time']
    precip[ii] = np.array(precip[ii], dtype = float)
    dates[ii] = np.array(dates[ii], dtype = str)

df = pd.DataFrame(precip)
print(df)

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Все данные о станциях c находятся внутри my_dict['STATION'], который содержит словарь для каждой станции, каждая из которых имеет ключ 'OBSERVATIONS'. Значение в словаре под этим ключом содержит значения временных рядов, содержащиеся в двух ключах: date_time и precip_accum_set_1.

. Чтобы получить данные в информационном кадре, мы хотим получить доступ к этому ключу 'OBSERVATIONS' для каждая станция. Вы можете сделать это с пониманием списка. Этот список содержит два словаря (по одному для каждой станции), каждый из которых имеет два ключа date_time наблюдения и precip_accum_set_1

my_list = [station['OBSERVATIONS'] for station in my_dict['STATION']]

. Чтобы получить каждый из них на фрейме данных, вы можете использовать pd.DataFrame.from_dict:

list_df = [pd.DataFrame.from_dict(d).set_index('date_time') for d in my_list]

Если вы хотите создать один кадр данных с обеими станциями, используйте pd.concat и используйте названия станций из my_dict['STATION'] как keys:

my_df = pd.concat(list_df, keys=[station['NAME'] for station in my_dict['STATION']], names=['NAME'])
my_df.head()
                                    precip_accum_set_1
NAME        date_time   
STATION 1   2020-04-13T13:00:00Z    0.000
            2020-04-13T14:00:00Z    0.000
            2020-04-13T15:00:00Z    0.000
            2020-04-13T16:00:00Z    0.254
            2020-04-13T17:00:00Z    1.270


my_df.tail()
                                    precip_accum_set_1
NAME        date_time   
STATION 2   2020-04-14T14:00:00Z    76.708
            2020-04-14T15:00:00Z    76.708
            2020-04-14T16:00:00Z    76.708
            2020-04-14T17:00:00Z    76.708
            2020-04-14T18:00:00Z    NaN

Исходя из ваших потребностей, вы можете преобразовать его по мере необходимости:

  1. Транспонировать данные с помощью my_df.T, чтобы получить 60 столбцов (одна строка со столбцом для каждой комбинации станция / время)
  2. Возврат одной строки на станцию ​​и одного столбца за раз с помощью my_df.unstack()
  3. Поворот данных для получения одной строки за раз и одного столбца за станцию ​​с помощью my_df.reset_index(level='NAME').pivot(columns='NAME', values='precip_accum_set_1')
  4. Преобразование индекса из строки на текущее время с pd.to_datetime

Примечание: Ваш пример словаря имеет несовпадающее число date_time (30) и precip_accum_set_1 (29) наблюдения за STATION 2, которые необходимо учесть, чтобы пример работал. Я добавил np.nan, чтобы пример работал, но вы должны убедиться, что реальные данные не вызывают вашу проблему.

0 голосов
/ 23 апреля 2020

Следующий код с выводом фрейма данных с тем же количеством столбцов, что и значения данных, дайте мне знать, если я неправильно понял, на какой формат фрейма данных вы рассчитывали:

# code as in your question


precip = [my_dict['STATION'][ii]['OBSERVATIONS']['precip_accum_set_1'] for ii in range(no_stations)]
dates = [my_dict['STATION'][ii]['OBSERVATIONS']['date_time'] for ii in range(no_stations)]

precip_df = pd.DataFrame(precip)
print(precip_df)

dates_df = pd.DataFrame(dates)
print(dates_df)

Вывод:

precip_df:
      0      1      2       3       4   ...      25      26      27      28     29
0   0.00   0.00   0.00   0.254   1.270  ...  27.686  27.686  27.686  27.686  27.94
1  49.53  49.53  49.53  50.038  51.054  ...  76.708  76.708  76.708  76.708    NaN

[2 rows x 30 columns]

dates_df:
                      0  ...                    29
0  2020-04-13T13:00:00Z  ...  2020-04-14T18:00:00Z
1  2020-04-13T13:00:00Z  ...  2020-04-14T18:00:00Z

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