В следующем фрейме данных df ...
import string, random
import pandas as pd
random.seed(1234)
sz = 1000
c = pd.Series(random.choice(string.ascii_uppercase[:8]) for _ in range(sz))
d = pd.Series(random.randint(0,30) for _ in range(sz))
v = pd.Series(random.randint(i, i+30) for i in range(sz))
df = pd.DataFrame({'c': c, 'd': d, 'v': v}) # the dataframe
... хотел бы получить фрейм данных с самыми высокими значениями для каждой группы на основе словаря заголовков:
hds = {'A': 2, 'B': 3, 'D': 1}
Ожидаемый результат:
введите описание изображения здесь
... который я получил с помощью следующего кода:
dfs = []
# require result by group of `c` and `d`
g = df.sort_values(['c', 'd'], ascending=[True, False]).groupby(['c', 'd'])
for s in hds.keys():
dfs.append(g.apply(lambda x: x[x.c == s][['v']].head(hds[s])))
dfr = pd.concat(dfs)
dfr1 = dfr.reset_index().set_index('level_2')
dfr1.index.rename('orig_index', inplace=True)
Есть ли более быстрый способ векторизации для достижения вышеуказанного? Пробовал ...
g.apply(lambda x: x.head(y) for y in [hds[s] if s in hds else 0 for s in list(hds.keys())])
... но он дает:
TypeError: объект 'generator' не вызывается