Pandas 基于条件将筛选器应用于数据帧
我有这个df:Pandas 基于条件将筛选器应用于数据帧,pandas,Pandas,我有这个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, 1
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
]
})
我需要使用以下逻辑对其应用过滤器:
- 如果球队排名1-4,最多保留4项
- 如果团队排名为5-12,则最多保留3项
- 如果球队排名12-16,最多保留2项
- 如果为17-20,则最多保留1项
- 当删除超过配额的项目时,删除点数较少的项目
Teams /
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
Y
Z
让我们使用
pd.cut
将排名映射到要提取的行数,然后使用groupby().cumcount()将其与相对行数进行比较:
输出:
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
我尝试了一个解决方案,但答案与您所写的完全不同,可能是因为输入错误。不管怎样,这是一种你想做的事情
为了提高可读性,我创建了一个函数,根据项目的等级返回要保留的项目数
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)
排名5-2
你的意思是5-12
?是的,对不起,我不明白为什么E,Y,Z
在排名8分中被选中1:E,J,Y,Z
。也就是说,在相同等级、相同分数的情况下,你有什么偏好吗?@QuangHoang在这种情况下,随机下降……不应该sort_values()
haveascending=False
,以获得更高的值?@8位博尔赫斯:是的。谢谢你接电话。不知怎的,我把你的问题理解为选择/保留较低的点
。
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)
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