#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
У меня есть csv-файл с разными группами, идентифицируемыми идентификатором, что-то вроде:
ID,X
aaa,3
aaa,5
aaa,4
bbb,50
bbb,54
bbb,52
Мне нужно:
- вычислите среднее значение x в каждой группе;
- разделите каждое значение x на среднее значение x для этой конкретной группы.
Итак, в моем примере выше среднее значение в группе ‘aaa’ равно 4, а в ‘bbb’ — 52. Мне нужно получить новый фрейм данных с третьим столбцом, где в каждой строке у меня есть исходное значение x, деленное на среднее значение по группе:
ID,X,x/group_mean
aaa,3,3/4
aaa,5,5/4
aaa,4,4/4
bbb,50,50/52
bbb,54,54/52
bbb,52,52/52
Я могу сгруппировать фрейм данных и вычислить среднее значение каждой группы по:
df_data = pd.read_csv('test.csv', index_col=0)
df_grouped = df_data.groupby('ID')
for group_name, group_content in df_grouped:
mean_x_group = group_content['x'].mean()
print(f'mean = {mean_x_group}')
но как мне добавить третий столбец?
Ответ №1:
Используйте Groupby.transform
:
In [1874]: df['mean'] = df.groupby('ID').transform('mean')
In [1879]: df['newcol'] = df.X.div(df['mean'])
In [1880]: df
Out[1880]:
ID X mean newcol
0 aaa 3 4 0.750000
1 aaa 5 4 1.250000
2 aaa 4 4 1.000000
3 bbb 50 52 0.961538
4 bbb 54 52 1.038462
5 bbb 52 52 1.000000
Комментарии:
1. Хорошо, что об этом напоминают
.tranform
в groupby. Я часто просто использую.agg
только для того, чтобы найти способ транслировать среднее значение для всех строк. Для этого.
Ответ №2:
Идея заключается в аккуратном однострочном:
df['new_column'] = df.apply(lambda row: row.X/df.loc[df.ID==row.ID, 'X'].mean(), axis=1)
Комментарии:
1. Хотя это не очень аккуратно!!
2. Это аккуратно в том смысле, что, так сказать, ближе к разговорному языку. «Для каждой строки возьмите X и разделите его на среднее значение». Независимо от аккуратности или нет, я думаю, что все же полезно использовать больше подходов к проблеме, чтобы вдохновить другие идеи и для других проблем.
3. Конечно, я согласен с этим.
Ответ №3:
Один линейный код для этого
# divide X with mean of X group by ID
df['group_mean'] = df.X / df.groupby('ID').transform('mean').X