#python #python_3x #pandas #dataframe
Есть два DataFrame с временными затратами за день и на отдельные задачи: d = [('20190601', 7.0), ('20190602', 8.0)] t = [('20190601', 'task1', 5.0), ('20190601', 'task2', 1.0), ('20190602', 'task1', 4.0), ('20190602', 'task2', 3.0)] ddf = pd.DataFrame(d, columns=['date', 'fact']) tdf = pd.DataFrame(t, columns=['date', 'task', 'fact']) Подсчитываю сумму времнных затрат всех задач за день: sumdf = tdf.groupby([tdf.date]).fact.sum().reset_index() date fact 0 20190601 6.0 1 20190602 7.0 Потом пытаюсь объединить в конечный DataFrame: df = pd.concat([ddf, tdf], axis=0, ignore_index=True, sort=False) df.sort_values(['date', 'task'], na_position='first', inplace=True) date fact task 0 20190601 7.0 NaN 2 20190601 5.0 task1 3 20190601 1.0 task2 1 20190602 8.0 NaN 4 20190602 4.0 task1 5 20190602 3.0 task2 Но не совсем понимаю, как лучше добавить также и суммы из sumdf, чтобы получилось: date fact task calc 0 20190601 7.0 NaN 6.0 2 20190601 5.0 task1 NaN 3 20190601 1.0 task2 NaN 1 20190602 8.0 NaN 7.0 4 20190602 4.0 task1 NaN 5 20190602 3.0 task2 NaN То есть, суммы за день должны оказаться в новой колонке calc только для строк где task=NaN. Как выполнить такое объединение наиболее эффективно? По возможности, без промежуточного подсчета сумм за день.
Ответы
Ответ 1
Как-то так: res = (pd.concat((tdf, ddf.merge(tdf.groupby("date") ["fact"] .sum() .reset_index(name="calc"), on="date")), ignore_index=True, sort=False) .sort_values(['date', 'task'], na_position='first')) результат: In [33]: res Out[33]: date task fact calc 4 20190601 NaN 7.0 6.0 0 20190601 task1 5.0 NaN 1 20190601 task2 1.0 NaN 5 20190602 NaN 8.0 7.0 2 20190602 task1 4.0 NaN 3 20190602 task2 3.0 NaNОтвет 2
Сначала выделяем строки из df, которым нужно подставить значение: temp1 = df.loc[df['task'].isna()] Затем достаём нужные значения из sumdf: temp2 = temp1.merge(sumdf, on='date', how='left', indicator=True) Остаётся лишь создать новый столбец: df['calc'] = np.NaN И подставить полученные значения в нужных местах: df.loc[df['task'].isna(), 'calc'] = temp2['fact_y'] Результат: date fact task calc 0 20190601 7.0 NaN 6.0 2 20190601 5.0 task1 NaN 3 20190601 1.0 task2 NaN 1 20190602 8.0 NaN 7.0 4 20190602 4.0 task1 NaN 5 20190602 3.0 task2 NaN
Комментариев нет:
Отправить комментарий