Python 过滤多索引分组数据帧

Python 过滤多索引分组数据帧,python,pandas,dataframe,filter,multi-index,Python,Pandas,Dataframe,Filter,Multi Index,数据如下所示: id timestamp date value 1 2001-01-01 2001-05-01 0 1 2001-10-01 2001-05-01 1 2 2001-01-01 2001-05-01 0 2 2001-10-01 2001-05-01 0 如您所见,该表包含id、timestamp、date和value列。 具有相同id的每一行也具有相同的日期。 此外,date在时间上总是在每个id的第一个和最后一个时间戳之间

数据如下所示:

id  timestamp   date        value
1   2001-01-01  2001-05-01  0
1   2001-10-01  2001-05-01  1
2   2001-01-01  2001-05-01  0
2   2001-10-01  2001-05-01  0
如您所见,该表包含
id
timestamp
date
value
列。 具有相同
id
的每一行也具有相同的
日期
。 此外,
date
在时间上总是在每个
id
的第一个和最后一个
时间戳之间的某个位置

任务是以删除每个
id
的方式过滤表,该id在其各自的
日期
后的时间戳中至少不包含一个
值>0
的条目

我实现它的方式是使用
level0=id
level1=date
对表进行多索引并对其排序。然后我将其按
级别0
分组。接下来,我循环遍历每个组(
id
),并分配一个新值,告诉我
id
是否为“好”(布尔值)。最后,我过滤good为True的表

不幸的是,对于一个大的(>10M行)数据集来说,这个实现非常缓慢。 我正在寻找一种加速的方法。我的想法是使用
groupby.apply(lambda g:something)
,但我没有让它发挥作用,我不知道这是否是最快的选择

工作代码示例:

import pandas as pd

df = pd.DataFrame({'id': [1, 1, 2, 2],
                   'timestamp': ['01-01-2001', '01-10-2001', '01-01-2001', '01-10-2001'], 
                   'date': ['01-05-2001', '01-05-2001', '01-05-2001', '01-05-2001'],
                   'value': [0, 1, 0, 0]})                               

df['timestamp'] = pd.to_datetime(df['timestamp'])
df['date'] = pd.to_datetime(df['date'])
df = df.set_index(['id','timestamp']).sort_index()
grouped = df.groupby(level=0)
df['good'] = False
for i,(id,df_id) in enumerate(grouped):
    index = df_id.index
    df_id = df_id.droplevel(0)
    df.good.loc[index] = any(df_id.value.loc[df_id.date[0]:] > 0)
df = df[df.good == True]

对于按
列中的
1
获取所有
id
s以及
时间戳
更高,如
date
创建两个掩码,按
按位链接
,然后测试每组是否至少有一个
True
,以及:


哇,谢谢!如果我想在日期中添加一些天作为“缓冲区”,比如
import datetime any(df_id.value.loc[df_id.date[0]+datetime.timedelta(days=1):]>0
@gustavz-你认为像
m=df['value'].gt(0)&df['timestamp'].gt(df['date']+pd.timedelta(days=1))吗
?如果我想知道,我将如何更改您的代码:为每个
id
,提供
date
之后从第一个大于
0
的值开始的所有时间数据。因此,不仅是在某个日期之后大于零的所有数据,而且是从时间第一个大于零的值开始的日期之后的数据。@gustavz-N我不确定是否理解,您是否可以添加一些具有预期输出的示例数据,@gustavz-您现在可以检查吗?我认为您创建了新问题;),因为这里隐藏了3个问题;)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['date'] = pd.to_datetime(df['date'])
df = df.sort_values(['id','timestamp'])

m = df['value'].gt(0) & df['timestamp'].gt(df['date'])
df = df[m.groupby(df['id']).transform('any')]
print (df)
   id  timestamp       date  value
0   1 2001-01-01 2001-01-05      0
1   1 2001-01-10 2001-01-05      1