我有这个df:
df = pd.DataFrame({
'Team': [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z'
],
'Ranking': [
2, 6, 6, 1, 8, 9, 16, 6, 16, 8, 6, 3, 1, 16, 9, 1, 2, 1, 16, 16, 16, 9, 9, 8, 8
],
'Points': [
1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1
]
})
我需要使用以下逻辑对其应用过滤器:
如何将上述逻辑应用于数据框?
所需结果:
Teams /
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
Y
Z
答案 0 :(得分:1)
让我们使用pd.cut
将排名映射到要提取的行数,然后使用groupby().cumcount()
将它们与相对行数进行比较:
thresh = pd.cut(df['Ranking'], bins=[0,4,12,16,20],
labels=[4,3,2,1]).astype(int)
df.loc[df.sort_values(['Points'])
.groupby('Ranking').cumcount().lt( thresh), 'Team']
输出:
0 A
1 B
2 C
3 D
4 E
5 F
7 H
11 L
12 M
15 P
16 Q
17 R
19 T
20 U
21 V
22 X
23 Y
24 Z
Name: Team, dtype: object
答案 1 :(得分:0)
我已经尝试了一种解决方案,但是答案可能与您写的答案有很大出入,可能是因为有误。无论如何,这是您想要做的一种方式。
为了提高可读性,我创建了一个函数,用于根据项目的排名返回要保留的项目数。
def items2keep(ranking):
return 4 if ranking < 5 else 3 if ranking < 13 else 2 if ranking < 17 else 1
result = []
for rank in df['Ranking'].unique():
_df = df[df['Ranking'] == rank].nlargest(
n=items2keep(rank),
columns=['Points']
)
result.append(_df)
final_df = pd.concat(result)
如果我们打印final_df
,则会得到:
print(final_df.sort_values(['Ranking', 'Points'], ascending=[True, False]))
Team Ranking Points
15 P 1 3
3 D 1 1
12 M 1 1
17 R 1 1
0 A 2 1
16 Q 2 1
11 L 3 1
1 B 6 1
2 C 6 1
7 H 6 1
9 J 8 2
4 E 8 1
23 Y 8 1
14 O 9 3
5 F 9 2
21 V 9 1
6 G 16 1
8 I 16 1