Эффективное преобразование списка словарей со встроенными массивами в DataFrame - PullRequest
1 голос
/ 15 марта 2019

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

data = [  {
    'date': '2018-01-01',
    'measurement': 100,
    'responses': [(1, 1, np.array([1, 2, 3])),
                (2, 1, np.array([4, 5, 6])),
               ]
   },
   {
    'date': '2018-01-02',
    'measurement': 200,
    'responses': [(3, 1,np.array([5, 6, 7])),
                (4, 1, np.array([8, 9, 10])),
               ]
   },
]

И имена столбцов для длин волн для сопоставления:

wavelengths = [400,401,402]

Я хотел бы преобразовать этот список в два кадра данных панд;

  1. Один, где массив в кортежах ответов усредняется, и
  2. Один, где они являются отдельными, где включены первые числа в кортеже в ответах.

Ниже приведены желаемые результаты для обоих:

__Average Dataframe__
index | date           | measurement | 400   | 401   | 402   |
0     | '2018-01-01'   | 100         | 2.5   | 3.5   | 4.5   |
1     | '2018-01-02'   | 200         | 6.5   | 7.5   | 8.5   |


__Seperate Dataframe__
index | date           | measurement | prong | scan| 400 | 401 | 402 |
0     | '2018-01-01'   | 100         | 1     | 1   | 1   | 2   | 3   |
1     | '2018-01-01'   | 100         | 2     | 1   | 4   | 5   | 6   |
2     | '2018-01-02'   | 200         | 3     | 1   | 5   | 6   | 7   |
3     | '2018-01-02'   | 200         | 4     | 1   | 8   | 9   | 10  |

Какой самый эффективный способ сделать это в пандах?

1 Ответ

0 голосов
/ 15 марта 2019

Возможно, это не идеальное решение, но использование pandas:

import pandas as pd

wavelengths= [400, 401,402]
cols = ['prong', 'scan'] + wavelengths 

df1 = pd.concat([pd.DataFrame(dict([(k, pd.Series(v)) for k, v in d.items()])) for d in data])
df1 = df1.reset_index(drop=True).ffill()
df2 = pd.DataFrame([(x,y,*z) for x,y,z in df1['responses']], columns= cols)

df = pd.concat([df1.drop('responses', 1), df2], 1)
# Separate dataset
         date  measurement  prong  scan  400  401  402
0  2018-01-01        100.0      1     1    1    2    3
1  2018-01-01        100.0      2     1    4    5    6
2  2018-01-02        200.0      3     1    5    6    7
3  2018-01-02        200.0      4     1    8    9   10

df.groupby(['date', 'measurement'])[wavelengths].mean().reset_index()
# Average dataset
         date  measurement  400  401  402
0  2018-01-01        100.0  2.5  3.5  4.5
1  2018-01-02        200.0  6.5  7.5  8.5
...