Несколько списков словарей для панда данных - PullRequest
2 голосов
/ 02 апреля 2019

Я извлекаю данные из API, и он возвращает список словарей для каждой записи, которую мне нужно поместить в панду DataFrame. Что делает это трудным, так это то, что извлекаемые словари всегда разные.

3 примера:

[{'name': 'A', 'value': '1'},
 {'name': 'B', 'value': 'DateTimeValue'},
 {'name': 'C', 'value': '15'}]

[{'name': 'A', 'value': '2'},
 {'name': 'D', 'value': 'StringValue'},
 {'name': 'C', 'value': '15'}]

[{'name': 'A', 'value': '5'},
 {'name': 'B', 'value': 'DateTimeValue'},
 {'name': 'C', 'value': '19'},
 {'name': 'F', 'value': '25.123'}]

Мне нужно, чтобы значения 'name' были столбцами в DF, а значения 'value' были строками. В последнем приложении мне нужно будет вытащить несколько сотен из них за один раз в цикле for.

Самое близкое, что я получил, - это создание нескольких однострочных фреймов данных в цикле for и попытка объединить их. Однако слияние только что создало новые столбцы с _y и _x. Мне нужен фрейм данных, чтобы создавать новые столбцы, только когда появляется новое имя, например, F выше.

Вот что я попробовал

df = pd.DataFrame(columns=['A']) # A is the only common column 

for dict in dict_list:

    data = getdata(API_stuff = ApiStuff, dicts = dict) #returns one list of dicts

    df1 = pd.DataFrame(dict) #get the data of one dict
    df1 = df1.transpose() 
    df1.reset_index(inplace=True) 
    df1 = df1.drop(columns= ['index'])
    df1.columns = df1.loc[0] # makes the column names the dict 'names'
    df1.drop(df1.index[0],inplace=True) # drop the duplicate row
    df1.index = ['Message-ID']
    # the above code creates a one row dataframe with the 'name' values as columns

    df = pd.merge(df, df1, on='A', how='outer') # merge one df on the previous ones

Вывод следующий:

   A  B  C  A_x  D  C_x  A_y  B_x  C_y  F  
0  1  DT 15
1           2   SV  15
2                         5   DT    19  25.123

С NaN в пустых пространствах

Мне нужно, чтобы вывод был

   A    B    C    D     F   
0  1   DT   15   NaN   NaN
1  2   NaN  15   SV    NaN      
2  5   DT   19   NaN   25.123               

Я знаю, что есть лучший способ сделать это, но у меня проблемы с соединением частей. Спасибо!

1 Ответ

2 голосов
/ 02 апреля 2019

Конструктор pd.DataFrame может справиться с этим, если вы предоставите его в правильной форме, например:

In [8]: dict_list
Out[8]:
[[{'name': 'A', 'value': '1'},
  {'name': 'B', 'value': 'DateTimeValue'},
  {'name': 'C', 'value': '15'}],
 [{'name': 'A', 'value': '2'},
  {'name': 'D', 'value': 'StringValue'},
  {'name': 'C', 'value': '15'}],
 [{'name': 'A', 'value': '5'},
  {'name': 'B', 'value': 'DateTimeValue'},
  {'name': 'C', 'value': '19'},
  {'name': 'F', 'value': '25.123'}]]

In [9]: pd.DataFrame([{d['name']:d['value'] for d in ds} for ds in dict_list])
Out[9]:
   A              B   C            D       F
0  1  DateTimeValue  15          NaN     NaN
1  2            NaN  15  StringValue     NaN
2  5  DateTimeValue  19          NaN  25.123
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...