筛选多索引分组大熊猫数据框

时间:2020-04-07 06:59:48

标签: 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

如您所见,该表包含列idtimestampdatevalue。 具有相同id的每一行也具有相同的date。 此外,date总是在时间上始终位于每个timestamp的第一个id与最后一个id之间。

任务是对表格进行过滤,以删除每个value > 0,每个date在其各自的{{之后, 1}}。

我用level 0 = idlevel 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]

1 个答案:

答案 0 :(得分:2)

要获得id列中1的所有value,并且timestamp更高,就像dateSeries.gt创建2个遮罩,按&进行按位AND链接,然后按GroupBy.anyGroupBy.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