熊猫:如果满足条件,则删除行

时间:2020-10-14 16:47:35

标签: python pandas

我有一个数据框,如:

date                airport_id  plane_type    runway
2020-01-01            11        333           3
2020-01-01            11        222           3
2020-01-02            11        333           3
2020-01-02            11        222           3
2020-01-03            11        333           3
2020-01-04            11        222           3
2020-01-01            12        222           3
2020-01-01            12        345           4

在给定的日期,如果plane_type相同,则不能出现两种类型的平面(runway),从而删除具有较大plane_type的行

预期输出:

date                airport_id  plane_type    runway
2020-01-01            11        222           3
2020-01-02            11        222           3
2020-01-03            11        333           3
2020-01-04            11        222           3
2020-01-01            12        222           3
2020-01-01            12        345           4

任何帮助将不胜感激!谢谢

2 个答案:

答案 0 :(得分:1)

对于给定的plane_typedateairport_id,您似乎希望采用最小的plane_type。您可以通过groupby语句来做到这一点,如下所示:

result = (
    df.groupby(['date', 'airport_id', 'runway'], as_index=False)['plane_type'].min()
   .sort_values(['airport_id', 'runway'])
)
>>> result
         date  airport_id  runway  plane_type
0  2020-01-01          11       3         222
3  2020-01-02          11       3         222
4  2020-01-03          11       3         333
5  2020-01-04          11       3         222
1  2020-01-01          12       3         222
2  2020-01-01          12       4         345

然后,您可以将其他列(例如citycountry)合并回到该结果,假设这些值对于给定的合并键是唯一的。

result.merge(df, on=['date', 'airport_id', 'runway', 'plane_type'])

答案 1 :(得分:0)

从您的预期输出中,我看到应该添加 关于 airport_id 的要求:

  • 没有两种类型的飞机...
  • 在任何给定的 airport_id 中(这是要添加的部分)
  • 如果它们具有相同的跑道

要生成此结果,请运行:

result = df.groupby(['date', 'airport_id', 'runway'], as_index=False,
    sort=False).apply(lambda grp: grp[grp.plane_type == grp.plane_type.min()])\
    .reset_index(level=0, drop=True)

结果是:

        date  airport_id  plane_type  runway
1 2020-01-01          11         222       3
3 2020-01-02          11         222       3
4 2020-01-03          11         333       3
5 2020-01-04          11         222       3
6 2020-01-01          12         222       3
7 2020-01-01          12         345       4

也尝试另一个概念,即:

  • 首先将分组列设置为索引,
  • 然后 groupby
  • 最后一点-将索引列改回“普通”列。

执行此操作的代码是:

result = df.set_index(['date', 'airport_id', 'runway'])\
    .groupby(['date', 'airport_id', 'runway'], as_index=False)\
    .apply(lambda grp: grp[grp.plane_type == grp.plane_type.min()])\
    .reset_index(level=[1,2,3])

通过索引访问应该要快得多,所以如果执行 速度是问题,这可能是更好的方法。