У меня есть Pandas DataFrame, который выглядит следующим образом:

data = {'user_id':[1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3],
        'time':[10, 12, 11, 20, 40, 41, 42, 100, 60, 22, 0, 3],
        'height':[1.23, 1.1, 0.5, 10.3, 3.33, 4.55, 2.22, 2.21, 2.25, 7.75, 9.2, 5.5],
        'width':[3, 4, 6, 2, 4, 8, 9, 0, 6, 6, 6, 4]}
df = pd.DataFrame(data)

Теперь я хотел бы вычесть из каждого столбца (кроме столбца user_id) среднее значение, сгруппированное по user_id. Это означает, что для user_id 1 среднее значение для time равно 13,25 ((10 + 12 + 11 + 20) / 4), поэтому 13,25 вычитается из 10, 12, 11 и 20, что приводит к

'time':[-3.25, -1.25, -2.25, 6.75, 40, 41, 42, 100, 60, 22, 0, 3]

Это я хотел бы сделать для всех столбцов и всех пользователей. Как это может быть сделано?

1
machinery 28 Май 2019 в 20:11

2 ответа

Лучший ответ

Это то, что вы хотите?

df[df.columns.difference(['user_id'])].sub(df.groupby('user_id').transform('mean'))

От @piRSquare:

df.update(df - df.groupby('user_id').transform('mean'))

Или

df.loc[:, ['height', 'time', 'width']] -= df.groupby('user_id').transform('mean')    

От @ anky_91:

df.drop('user_id',1).sub(df.groupby('user_id').time.transform('mean'),axis=0)


Out[2054]:
      height   time  width
0  -2.052500  -3.25  -0.75
1  -2.182500  -1.25   0.25
2  -2.782500  -2.25   2.25
3   7.017500   6.75  -1.75
4  -0.036667  -1.00  -3.00
5   1.183333   0.00   1.00
6  -1.146667   1.00   2.00
7  -3.172000  63.00  -4.40
8  -3.132000  23.00   1.60
9   2.368000 -15.00   1.60
10  3.818000 -37.00   1.60
11  0.118000 -34.00  -0.40
3
Andy L. 28 Май 2019 в 17:42

Вы можете использовать groupby.transform для создания массива той же формы, что и ваш фрейм данных. Затем вычтите это из вашего time столбца:

m = df.groupby('user_id')['time'].transform('mean')

df['time'].add(-m)

0     -3.25
1     -1.25
2     -2.25
3      6.75
4     -1.00
5      0.00
6      1.00
7     63.00
8     23.00
9    -15.00
10   -37.00
11   -34.00
Name: time, dtype: float64

Вывод m приводит к:

print(m)

0     13.25
1     13.25
2     13.25
3     13.25
4     41.00
5     41.00
6     41.00
7     37.00
8     37.00
9     37.00
10    37.00
11    37.00
Name: time, dtype: float64
4
Erfan 28 Май 2019 в 17:20