熊猫:分组并根据条件在每个组中删除行
Posted
技术标签:
【中文标题】熊猫:分组并根据条件在每个组中删除行【英文标题】:Pandas: Groupby and drop rows in each group based on conditon 【发布时间】:2021-07-18 18:13:28 【问题描述】:我有一个数据框:
Name StartPoint EndPoint isDelivered Customer
0 A 1 4 0 C1
1 A 1 4 0 C1
2 A 2 5 1 C1
3 A 3 5 0 C1
4 A 3 6 0 C1
5 A 3 6 1 C1
6 B 1 4 0 C2
7 B 1 4 0 C2
8 B 2 5 1 C2
9 B 3 5 1 C2
10 B 3 6 1 C2
11 B 3 8 0 C2
12 B 3 8 1 C2
我想按Name
分组,每个组应该有满足以下条件的行:
StartPoint
列中的最小值
EndPoint
列中的最大值和isDelivered
列中的值 1
这就是我所做的:
groups = df.groupby(['Name']).StartPoint
groups1 = df.groupby(['Name']).EndPoint
min_StartPoint = groups.transform(min)
max_EndPoint = groups1.transform(max)
df1 = df[(df.StartPoint==min_StartPoint)|(df.EndPoint==max_EndPoint)]
得到的结果是:
Name StartPoint EndPoint isDelivered Customer
0 A 1 4 0 C1
1 A 1 4 0 C1
4 A 3 6 0 C1
5 A 3 6 1 C1
6 B 1 4 0 C2
7 B 1 4 0 C2
11 B 3 8 0 C2
12 B 3 8 1 C2
但第 4 行和第 11 行在 isDelivered
中没有值 1,因此它们不满足第二个条件。
我想要的结果是:
Name StartPoint EndPoint isDelivered Customer
0 A 1 4 0 C1 # Min value in StartPoint
1 A 1 4 0 C1 # Min value in StartPoint
5 A 3 6 1 C1 # Max value in EndPoint and 1 in isDelivered
6 B 1 4 0 C2 # Min value in StartPoint
7 B 1 4 0 C2 # Min value in StartPoint
12 B 3 8 1 C2 # Max value in EndPoint and 1 in isDelivered
有没有办法使用我当前的解决方案来实现这一点?
【问题讨论】:
【参考方案1】:你在正确的轨道上,你只需要在最后一行代码中添加一个额外的条件:
df1 = df[(df.StartPoint==min_StartPoint)|((df.EndPoint==max_EndPoint)
& (df.isDelivered == 1))]
Name StartPoint EndPoint isDelivered Customer
0 A 1 4 0 C1
1 A 1 4 0 C1
5 A 3 6 1 C1
6 B 1 4 0 C2
7 B 1 4 0 C2
12 B 3 8 1 C2
【讨论】:
天啊,我意识到我使用的是逻辑“和”而不是按位“&”,这就是我没有得到结果的原因!我的一个愚蠢的错误。非常感谢您的回答!【参考方案2】:您从未合并第二个条件的两个子句。使您的代码反映给定的措辞:保存的行必须符合以下两个条件之一:
df1 = df[(df.StartPoint == min_StartPoint) |
((df.EndPoint == max_EndPoint) & df.isDelivered == 1)]
我很乐意向您展示实际输出,但您未能提供预期的输出,请参阅MRE - Minimal, Reproducible Example。
【讨论】:
非常感谢您的澄清!【参考方案3】:您可以对每个组应用过滤器:
df.groupby(['Name'], group_keys=False).apply(
lambda g:g[(g.StartPoint == g.StartPoint.min()) |
((g.EndPoint == g.EndPoint.max()) & (g.isDelivered == 1))])
输出:
Name StartPoint EndPoint isDelivered Customer
0 A 1 4 0 C1
1 A 1 4 0 C1
5 A 3 6 1 C1
6 B 1 4 0 C2
7 B 1 4 0 C2
12 B 3 8 1 C2
【讨论】:
感谢您的回答。我意识到我使用的是逻辑“and”而不是按位“&”,这就是我没有得到结果的原因。在发布问题之前我应该仔细检查一下。以上是关于熊猫:分组并根据条件在每个组中删除行的主要内容,如果未能解决你的问题,请参考以下文章