数据如下所示:
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
。
此外,date
总是在时间上始终位于每个timestamp
的第一个id
与最后一个id
之间。
任务是对表格进行过滤,以删除每个value > 0
,每个date
在其各自的{{之后, 1}}。
我用level 0 = id
和level 1 = date
对表进行多索引并对其进行排序的方式实现了它。然后,我按level 0
分组。接下来,我遍历每个组(id
)并分配一个新值,告诉我id
是否为“ good”(布尔值)。最终,我过滤了True
为好的表。
不幸的是,对于大型(> 1000万行)数据集,此实现速度慢得要命。
我正在寻找一种加快速度的方法。我的想法是使用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]
答案 0 :(得分:2)
要获得id
列中1
的所有value
,并且timestamp
更高,就像date
靠Series.gt
创建2个遮罩,按&
进行按位AND
链接,然后按GroupBy.any
和GroupBy.transform
测试每组至少一个True
:
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