从输入创建输出数据帧,当每个 id 第一次目标 == 1 时过滤行,或者按顺序删除目标为 1 的每个 id 的连续出现,但在目标 = 1 之前保留目标中的所有 0并在我们没有 1 的地方保留一组 id,例如 a0
输入
df = pd.DataFrame({'ID': ['a0','a0','a0','a1', 'a1', 'a1', 'a1', 'a1', 'a2', 'a2', 'a2', 'a2'],
'date': [ '2019-11-01',
'2019-12-01',
'2020-01-01',
'2019-11-01',
'2019-12-01',
'2020-01-01',
'2020-02-01',
'2020-03-01',
'2019-11-01',
'2019-12-01',
'2020-03-01',
'2020-04-01'],
'target': [0,0,0,0, 0, 1, 1, 0, 0, 1, 0, 1]})
输出
ID date target
a0 2019-11-01 0
a0 2019-12-01 0
a0 2020-01-01 0
a1 2019-11-01 0
a1 2019-12-01 0
a1 2020-01-01 1
a2 2019-11-01 0
a2 2019-12-01 1
答案 0 :(得分:2)
首先对数据帧进行排序。
df.sort_values(['ID', 'date'], inplace=True)
# use cumsum to calculate how many times the target eq 1
df['tag'] = df['target'] == 1
df['tag'] = df.groupby('ID')['tag'].cumsum()
# for every group use shift(1) to include the first 1
df['tag2'] = df.groupby('ID')['tag'].shift(1).fillna(0)
cond = df['tag2'] == 0
df[cond]
结果:
ID date target tag tag2
0 a0 2019-11-01 0 0.0 0.0
1 a0 2019-12-01 0 0.0 0.0
2 a0 2020-01-01 0 0.0 0.0
3 a1 2019-11-01 0 0.0 0.0
4 a1 2019-12-01 0 0.0 0.0
5 a1 2020-01-01 1 1.0 0.0
8 a2 2019-11-01 0 0.0 0.0
9 a2 2019-12-01 1 1.0 0.0
df:
ID date target tag tag2
0 a0 2019-11-01 0 0.0 0.0
1 a0 2019-12-01 0 0.0 0.0
2 a0 2020-01-01 0 0.0 0.0
3 a1 2019-11-01 0 0.0 0.0
4 a1 2019-12-01 0 0.0 0.0
5 a1 2020-01-01 1 1.0 0.0
6 a1 2020-02-01 1 2.0 1.0
7 a1 2020-03-01 0 2.0 2.0
8 a2 2019-11-01 0 0.0 0.0
9 a2 2019-12-01 1 1.0 0.0
10 a2 2020-03-01 0 1.0 1.0
11 a2 2020-04-01 1 2.0 1.0
答案 1 :(得分:1)
好问题。我相信 Ferris 的回答可能是一种优雅且计算效率高的方法。另一种直观的方法是考虑在数据帧上使用“应用”函数来为排序的数据帧中的每个组生成索引,我们应该在输出中包含哪一行。
df["ind"]=df.index
upto_id_index = df.groupby("ID").apply(lambda x: x[(x["target"]==1)]["ind"].min() if (x["target"].sum()>0) else x["ind"].max())
df[df.apply(lambda x: x["ind"]<= upto_id_index.loc[x["ID"]], axis=1)]
答案 2 :(得分:0)
使用 np.argmax
获取第一个元素的索引是可行的,但如何将所有行保持为 0,其中每个 id 没有目标 = 1
具有不同数据集的上一篇文章 (Pandas advanced groupby and filter by date)