删除特定列值第一次出现之后(包括)之后的行
Posted
技术标签:
【中文标题】删除特定列值第一次出现之后(包括)之后的行【英文标题】:Removing rows following (and including) the first occurrence of a particular column value 【发布时间】:2021-08-29 22:23:20 【问题描述】:我有一个非常大的 pd.Dataframe 包含数百万条记录,其中 PID
和 Ses_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:如何在特定类之后选择第一次出现的类