Моя общая цель - найти лучший рабочий процесс для создания прогнозов по многим моделям. Вот пример того, как я мог бы попытаться подогнать модели по группам в DataFrame и получить прогнозы вместе с данными, используемыми для прогнозирования:
from sklearn.linear_model import LinearRegression
import pandas as pd
start_data = pd.DataFrame({
'group': ['a'] * 3 + ['b'] * 3,
'x1': [1, 2, 3] * 2,
'x2': [4, 5, 6] * 2,
'y': [1, 3, 5, 2, 4, 6]
})
start_models = start_data\
.groupby('group')\
.apply(lambda group: LinearRegression().fit(group[['x1', 'x2']], group['y']))\
.to_frame(name = 'model')
new_data = pd.DataFrame({'x1': [11, 12, 13] * 2, 'x2': [7, 8, 9] * 2})
start_models['preds'] = start_models.model.apply(lambda model: model.predict(new_data))
start_models['newx1'] = start_models.model.apply(lambda model: new_data.x1.tolist())
start_models['newx2'] = start_models.model.apply(lambda model: new_data.x2.tolist())
Это дает DataFrame с каждой строкой, содержащей модель и связанные с ней прогнозы.
start_models
model ... newx2
group ...
a LinearRegression(copy_X=True, fit_intercept=Tr... ... [7, 8, 9, 7, 8, 9]
b LinearRegression(copy_X=True, fit_intercept=Tr... ... [7, 8, 9, 7, 8, 9]
В R было бы легко справиться с использованием tidyr::unnest
. Здесь я нашел этот вопрос , который предоставляет следующее решение, но также предполагает, что во-первых, избегать создания вложенного DataFrame предпочтительнее в pandas
.
start_models.drop(columns='model')\
.apply(lambda listcol: listcol.apply(pd.Series).stack())\
.reset_index()\
.drop(columns='level_1')
group preds newx1 newx2
0 a 14.0 11 7
1 a 16.0 12 8
2 a 18.0 13 9
3 a 14.0 11 7
4 a 16.0 12 8
5 a 18.0 13 9
6 b 15.0 11 7
7 b 17.0 12 8
8 b 19.0 13 9
9 b 15.0 11 7
10 b 17.0 12 8
11 b 19.0 13 9
Итак, вопрос в том, как следует думать о том, чтобы объединить модели и предсказания в pandas
? Другими словами, как мне перейти от start_data
к указанному выше выводу long
без использования списка-столбцов?
Возможно, использование списков-столбцов тоже подойдет, но я хотел спросить. Я не думаю, что этот путь слишком медленный с имеющимися у меня данными, но неловкость apply(pd.Series).stack()
подсказывает мне, что должен быть лучший или более намеченный способ сделать это. В частности, мне показалось очень удивительным, что функции, возвращающие Series из apply
, объединяются в строки DataFrame, особенно когда это не упомянуто в Series.apply
документах (хотя это в DataFrame.apply
), и это не работает, что путь для списков. Это больше похоже на обходной путь, чем на правильный рабочий процесс, если вы понимаете, о чем я!