Как ускорить перенос данных из одной таблицы в другую?
У меня есть два фрейма данных df и res. res получен в результате группировки df по столбцу name. Теперь мне нужно в df переписать дынные из столбца idxmaximum, полученного в таблице res, если значение в столбце name таблицы df совпадает со значением index в таблице res
Пример df таблицы:
| Name | Ноябрь | Декабрь | Февраль |
|---|---|---|---|
| Алексей | 15 | 10 | 15 |
| Алексей | 10 | 10 | 10 |
| Андрей | 15 | 25 | 15 |
| Алексей | 15 | 15 | 10 |
| Андрей | 25 | 10 | 45 |
Пример res таблицы:
| index | Ноябрь | Декабрь | Февраль | idxmaximum |
|---|---|---|---|---|
| Алексей | 40 | 35 | 35 | Ноябрь |
| Андрей | 40 | 35 | 60 | Февраль |
Что хочется получить:
| Name | Ноябрь | Декабрь | Февраль | num |
|---|---|---|---|---|
| Алексей | 15 | 10 | 15 | Ноябрь |
| Алексей | 10 | 10 | 10 | Ноябрь |
| Андрей | 15 | 25 | 15 | Февраль |
| Алексей | 15 | 15 | 10 | Ноябрь |
| Андрей | 25 | 10 | 45 | Февраль |
Мой код:
for i in range(df.shape[0]):
for j in range(res.shape[0]):
if df.name[i] == res.index[j]:
df.num[i] = res.idxmaximum[j]
Подскажите, пожалуйста, как можно ускорить данный процесс?
Ответы (2 шт):
скорее всего можно обойтись без вспомогательной переменной res, воспользовавшись векторизированным решением - groupby.SeriesGroupBy.transform().
Пример:
In [85]: df = pd.DataFrame([[1, 2, 8], [1, 4, 5], [2, 10, 11], [2, 9, 13]], columns=["id", "v1", "v2"])
In [86]: df
Out[86]:
id v1 v2
0 1 2 8
1 1 4 5
2 2 10 11
3 2 9 13
In [87]: df["new"] = df.groupby("id")["v2"].transform("idxmax")
In [88]: df
Out[88]:
id v1 v2 new
0 1 2 8 0
1 1 4 5 0
2 2 10 11 3
3 2 9 13 3
NOTE: комментарии по типу "ваш код не работает" / "у меня возникает ошибка" / etc. не принимаются без воспроизводимого примера данных в вопросе. ?
Ответ на уточненный вопрос с приведенным примером данных:
res = df.merge(df.groupby("Name").sum().idxmax(axis=1).reset_index(name="num"), how="left")
результат:
In [112]: res
Out[112]:
Name Ноябрь Декабрь Февраль num
0 Алексей 15 10 15 Ноябрь
1 Алексей 10 10 10 Ноябрь
2 Андрей 15 25 15 Февраль
3 Алексей 15 15 10 Ноябрь
4 Андрей 25 10 45 Февраль