删除特定列值第一次出现之后(包括)之后的行

Posted

技术标签:

【中文标题】删除特定列值第一次出现之后(包括)之后的行【英文标题】:Removing rows following (and including) the first occurrence of a particular column value 【发布时间】:2021-08-29 22:23:20 【问题描述】:

我有一个非常大的 pd.Dataframe 包含数百万条记录,其中 PIDSes_ID 都是索引列,Var_3 表示某些事件的发生。

PID Ses_ID Var_1 Var_2 Var_3
001 001002003 0.70.80.9 0.50.40.3 010
002 004005006007008 0.80.70.80.20.8 0.20.10.70.20.2 00101

我想从每个人的(由PID 索引)记录中删除/过滤掉第一次出现Var_3==1 之后的会话。因此,提供的示例将导致:

PID Ses_ID Var_1 Var_2 Var_3
001 001 0.7 0.5 0
002 004005 0.80.7 0.20.1 00

我可以迭代地将相关会话和对应的PID 添加到新数据帧中,但考虑到当前数据帧的大小,这将非常耗时。实现这一目标的有效方法是什么?非常感谢!

更新情况:我发现很多行都有相同的Ses_ID。如何在第一次出现特定列值之后(包括)删除会话?因此对于下面的示例,Ses_ID==005 的两行都将被删除,因为 Var_3==1 的事件发生在此会话中。

PID Ses_ID Var_1 Var_2 Var_3
001 001002003 0.70.80.9 0.50.40.3 010
002 009004004005005006007 0.10.80.80.70.80.20.8 0.30.10.20.10.70.20.2 0000101

应该转化为:

PID Ses_ID Var_1 Var_2 Var_3
001 001 0.7 0.5 0
002 009004004 0.10.80.8 0.30.10.2 000

【问题讨论】:

【参考方案1】:

您可以尝试使用布尔索引:

# assuming PID, Ses_ID are indices:
mask = df.groupby(level=0)["Var_3"].cumsum().eq(0)
print(df[mask])

打印:

            Var_1  Var_2  Var_3
PID Ses_ID                     
1   1         0.7    0.5      0
2   4         0.8    0.2      0
    5         0.7    0.1      0

编辑:

g = df.groupby(level=0)
df["Var_3"] = g["Var_3"].transform(
    lambda x: x.groupby(level=1).transform(sorted, reverse=True)
)
mask = g["Var_3"].cumsum().eq(0)
print(df[mask])

打印:

            Var_1  Var_2  Var_3
PID Ses_ID                     
1   1         0.7    0.5      0
2   4         0.8    0.2      0

【讨论】:

太棒了!非常感谢@Andrej!我发现许多行具有相同的Ses_ID,因为它们属于同一个会话。是否可以删除所有具有相同Ses_ID 的行,其中Var_3==1 出现(同时删除以下行)?我已经更新了这个问题。感谢您的帮助! @Blue482 您可以按相反的顺序对 Var_3 中的值进行排序,然后计算掩码。我更新了我的答案。 非常感谢@Andrej,这非常有效!尽管我对颠倒Var_3 的顺序如何做到这一点感到有些困惑。你能解释一下这里的逻辑吗?

以上是关于删除特定列值第一次出现之后(包括)之后的行的主要内容,如果未能解决你的问题,请参考以下文章

仅在包含另一个模式的另一行之后的第一次出现中替换包含模式的行

css selector jquery:如何在特定类之后选择第一次出现的类

在特定文本值 SQL Server 之后选择行

删除没有主键的重复项

Python 正则表达式。删除 ':' 之后的所有字符(包括行尾和特定字符串除外)

Jquery 在 DOM .append .after 之后获取更新的表格元素