У меня есть фрейм данных, d
:
Position Operation Side Price Size
9 9 0 1 0.7289 -16
8 8 0 1 0.729 -427
7 7 0 1 0.7291 -267
6 6 0 1 0.7292 -15
5 5 0 1 0.7293 -16
4 4 0 1 0.7294 -16
3 3 0 1 0.7295 -426
2 2 0 1 0.7296 -8
1 1 0 1 0.7297 -14
0 0 0 1 0.7298 -37
10 0 0 0 0.7299 6
11 1 0 0 0.73 34
12 2 0 0 0.7301 7
13 3 0 0 0.7302 9
14 4 0 0 0.7303 16
15 5 0 0 0.7304 15
16 6 0 0 0.7305 429
17 7 0 0 0.7306 16
18 8 0 0 0.7307 265
19 9 0 0 0.7308 18
Используйте приведенные ниже обновления для d
для перерасчета Position
:
d['Position'] = d.groupby('Side')['Price'].rank().astype('int').sub(1)
Но поскольку порядок сортировки различен для каждой Side
группы, есть ли способ отсортировать ascending
для одной группы и descending
для другой?
🤔 А знаете ли вы, что...
Синтаксис Python известен своей простотой и читаемостью.
Вы можете использовать groupby.apply для доступа к group.name
:
d['rank'] = (d.groupby('Side')['Price']
.apply(lambda x: x.rank(ascending=x.name==0).astype('int').sub(1))
.droplevel(0)
)
Выход:
Position Operation Side Price Size rank
9 9 0 1 0.7289 -16 9
8 8 0 1 0.7290 -427 8
7 7 0 1 0.7291 -267 7
6 6 0 1 0.7292 -15 6
5 5 0 1 0.7293 -16 5
4 4 0 1 0.7294 -16 4
3 3 0 1 0.7295 -426 3
2 2 0 1 0.7296 -8 2
1 1 0 1 0.7297 -14 1
0 0 0 1 0.7298 -37 0
10 0 0 0 0.7299 6 0
11 1 0 0 0.7300 34 1
12 2 0 0 0.7301 7 2
13 3 0 0 0.7302 9 3
14 4 0 0 0.7303 16 4
15 5 0 0 0.7304 15 5
16 6 0 0 0.7305 429 6
17 7 0 0 0.7306 16 7
18 8 0 0 0.7307 265 8
19 9 0 0 0.7308 18 9
Код
Я думаю, что простым решением является ранжирование групп путем умножения их цены на -1, при этом порядок ранжирования должен быть обратным.
cond = d['Side'].eq(1) # you can use isin when apply to multiple group
d['rank'] = (
d['Price']
.mask(cond, d['Price'].mul(-1))
.groupby(d['Side']).rank().astype('int').sub(1)
)