#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
Комментариев нет:
Отправить комментарий