#python #pandas #dataframe #group_by #статистика
Есть 2 pd.DataFrame: a = pd.DataFrame([[1, 20], [2, 25], [3, 24], [1, 22], [2, 29]], columns=['type', 'size']) b = pd.DataFrame([[1, 19], [1, 21], [2, 24], [4, 21]], columns=['type', 'size']) В каждый DataFrame хочу добавить столбцы следующего типа a['amount_mean_type'] = a['size'] / a.groupby('type')['size'].transform('mean') a['amount_std_type'] = a['size'] / a.groupby('type')['size'].transform('std') Вопрос в том, как мне сделать так, чтобы в b['amount_mean_type'] и b['amount_std_type'] я использовал mean и std по группам из a, а по тем категориям, которых нет в a, использовать mean и std по всему сету (если это корректно). Что-то вроде этого: b['amount_mean_type'] = b['size'] / a.groupby('type')['size'].transform('mean') b['amount_std_type'] = b['size'] / a.groupby('type')['size'].transform('std') Но только с теми условиями, которые описал выше UPD: пример фреймов на выходе Для a все просто: a['amount_mean_type'] = a['size'] / a.groupby('type')['size'].transform('mean') a['amount_std_type'] = a['size'] / a.groupby('type')['size'].transform('std') type size amount_mean_type amount_std_type 0 1 20 0.952381 14.142136 1 2 25 0.925926 8.838835 2 3 24 1.000000 NaN 3 1 22 1.047619 15.556349 4 2 29 1.074074 10.253048 для b приходится прописать вручную каждую операцию b.loc[0, 'amount_mean_type'] = b.loc[0, 'size'] / a[a['type'] == 1]['size'].mean() b.loc[1, 'amount_mean_type'] = b.loc[1, 'size'] / a[a['type'] == 1]['size'].mean() b.loc[2, 'amount_mean_type'] = b.loc[2, 'size'] / a[a['type'] == 2]['size'].mean() b.loc[3, 'amount_mean_type'] = b.loc[3, 'size'] / a['size'].mean() b.loc[0, 'amount_std_type'] = b.loc[0, 'size'] / a[a['type'] == 1]['size'].std() b.loc[1, 'amount_std_type'] = b.loc[1, 'size'] / a[a['type'] == 1]['size'].std() b.loc[2, 'amount_std_type'] = b.loc[2, 'size'] / a[a['type'] == 2]['size'].std() b.loc[3, 'amount_std_type'] = b.loc[3, 'size'] / a['size'].std() type size amount_mean_type amount_std_type 0 1 19 0.904762 13.435029 1 1 21 1.000000 14.849242 2 2 24 0.888889 8.485281 3 4 21 0.875000 6.192562 # Считается по всей переменной 'type', так как категории (4) нет в `a` Фреймы a и b можно рассматривать как train и test соответственно
Ответы
Ответ 1
tmp = a.groupby('type')['size'].agg(["mean", "std"]) res = (b.assign(x=b["type"].map(tmp["mean"]).fillna(a["size"].mean())) .eval("amount_mean_type = size / x") .drop(columns="x")) res = (res.assign(x=b["type"].map(tmp["std"]).fillna(a["size"].std())) .eval("amount_std_type = size / x") .drop(columns="x")) результат: In [28]: res Out[28]: type size amount_mean_type amount_std_type 0 1 19 0.904762 13.435029 1 1 21 1.000000 14.849242 2 2 24 0.888889 8.485281 3 4 21 0.875000 6.192562
Комментариев нет:
Отправить комментарий