熊猫:过滤groupby和/或透视?

时间:2020-01-04 18:01:22

标签: python pandas

我正试图弄清楚如何在大熊猫的群体情境中过滤比条件更大或更小的条件。

在样本df中,有7个组(a,b,c,d,e,f,g)。每个小组有1至6名玩家。是否可以筛选出玩家1在9-20之间得分的组?并显示玩家1得分在9-20之间的小组(如输出所示)?

ps。原始的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,]}

非常感谢 问候

3 个答案:

答案 0 :(得分:3)

IIUC,您可以将series.eqdf.groupby结合使用,将series.betweentransform结合使用:{p>

any

df[(df['players'].eq(1)&df['score'].between(9,20)).groupby(df['Group']).transform('any')]

答案 1 :(得分:3)

找到满足条件的组,然后使用#include <iostream> using namespace std; template<typename> struct PMClassT; template<typename C, typename M> struct PMClassT<M C::*> { using Type = C; }; template <typename PM> using PMClass = typename PMClassT<PM>::Type; template<auto PMD> struct CounterHandle { PMClass<decltype(PMD)>& c; CounterHandle(PMClass<decltype(PMD)> &c):c(c) { } void incr() { ++(c.*PMD); } }; struct S { int i; }; int main() { S s{ 41 }; CounterHandle<&S::i>h(s); h.incr(); return 0; } 筛选这些组中包含的数据。

isin

答案 2 :(得分:1)

使用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)]