[英]pandas: filtering groupby and/or pivot?
我試圖弄清楚如何在熊貓的組上下文中過濾大於/小於條件。
在樣本 df 中,有 7 個組(a、b、c、d、e、f、g)。 每組有 1 到 6 名玩家。 是否可以過濾掉 1 分在 9-20 之間的組? 並且將顯示玩家 1 得分在 9-20 之間的組(如輸出所示)?
附: 原始 df 大得多,其中包含超過 10 個玩家的組和其他具有可變值的列。
示例 df:
╔═══════╦════════╦═══════╗ ║ Group ║ player ║ score ║ ╠═══════╬════════╬═══════╣ ║ a ║ 1 ║ 10 ║ ║ a ║ 2 ║ 20 ║ ║ a ║ 3 ║ 29 ║ ║ a ║ 4 ║ 22 ║ ║ a ║ 5 ║ 14 ║ ║ b ║ 1 ║ 16 ║ ║ b ║ 2 ║ 16 ║ ║ b ║ 3 ║ 17 ║ ║ c ║ 1 ║ 22 ║ ║ c ║ 2 ║ 23 ║ ║ c ║ 3 ║ 22 ║ ║ d ║ 1 ║ 13 ║ ║ d ║ 2 ║ 13 ║ ║ d ║ 3 ║ 23 ║ ║ d ║ 4 ║ 13 ║ ║ d ║ 5 ║ 34 ║ ║ e ║ 1 ║ 32 ║ ║ e ║ 2 ║ 29 ║ ║ e ║ 3 ║ 28 ║ ║ e ║ 4 ║ 19 ║ ║ e ║ 5 ║ 19 ║ ║ e ║ 6 ║ 27 ║ ║ f ║ 1 ║ 47 ║ ║ f ║ 2 ║ 17 ║ ║ f ║ 3 ║ 14 ║ ║ f ║ 4 ║ 25 ║ ║ g ║ 1 ║ 67 ║ ║ g ║ 2 ║ 21 ║ ║ g ║ 3 ║ 27 ║ ║ g ║ 4 ║ 16 ║ ║ g ║ 5 ║ 14 ║ ║ g ║ 6 ║ 25 ║ ╚═══════╩════════╩═══════╝
所需輸出:
╔═══════╦════════╦═══════╗ ║ Group ║ player ║ score ║ ╠═══════╬════════╬═══════╣ ║ a ║ 1 ║ 10 ║ ║ a ║ 2 ║ 20 ║ ║ a ║ 3 ║ 29 ║ ║ a ║ 4 ║ 22 ║ ║ a ║ 5 ║ 14 ║ ║ b ║ 1 ║ 16 ║ ║ b ║ 2 ║ 16 ║ ║ b ║ 3 ║ 17 ║ ║ d ║ 1 ║ 13 ║ ║ d ║ 2 ║ 13 ║ ║ d ║ 3 ║ 23 ║ ║ d ║ 4 ║ 13 ║ ║ d ║ 5 ║ 34 ║ ╚═══════╩════════╩═══════╝
df代碼如下:
data = {'Group':['a','a','a','a','a','b','b','b','c','c','c','d','d','d','d','d',
'e','e','e','e','e','e','f','f','f','f','g','g','g','g','g','g'],
'players':[1,2,3,4,5,1,2,3,1,2,3,1,2,3,4,5,1,2,3,4,5,6,1,2,3,4,1,2,3,4,5,6],
'score':[10,20,29,22,14,16,16,17,22,23,22,13,13,23,13,34,32,29,28,19,19,27,47,17,14,25,67,21,27,16,14,25,]}
非常感謝
IIUC,您可以使用series.eq
與series.between
與df.groupby
和transform
與any
:
df[(df['players'].eq(1)&df['score'].between(9,20)).groupby(df['Group']).transform('any')]
Group players score
0 a 1 10
1 a 2 20
2 a 3 29
3 a 4 22
4 a 5 14
5 b 1 16
6 b 2 16
7 b 3 17
11 d 1 13
12 d 2 13
13 d 3 23
14 d 4 13
15 d 5 34
找到滿足條件的組,然后使用isin
過濾這些組中包含的數據。
df = pd.DataFrame(data)
groups_filter = (
df[df['players'].eq(1)
& df['score'].ge(9)
& df['score'].le(20)
]['Group'].unique()
)
>>> df[df['Group'].isin(groups_filter)]
Group players score
0 a 1 10
1 a 2 20
2 a 3 29
3 a 4 22
4 a 5 14
5 b 1 16
6 b 2 16
7 b 3 17
11 d 1 13
12 d 2 13
13 d 3 23
14 d 4 13
15 d 5 34
使用query
類似答案:
df = pd.DataFrame(data)
groups = df.query(" players == 1 & (9 <= score <= 20) ")["Group"].unique()
df.loc[df["Group"].isin(groups)]
使用切片更奢侈的答案:
idx = pd.IndexSlice
df_reid = df.set_index(["Group", "players"])
mask = df_reid[idx["score"]].between(9, 20)
groups = df_reid.loc[idx[mask,1],:].index.get_level_values("Group") # 1 means players == 1
df.loc[df["Group"].isin(groups)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.