gpt4 book ai didi

python - 如何按 ID 分组并用非空值标记第一行?

转载 作者:太空狗 更新时间:2023-10-30 02:51:10 25 4
gpt4 key购买 nike

ID 中,我需要删除具有 value > 0 的第一行以及数据框中包含有序日期列的所有行。我认为最简单的方法是创建一个新的 flag 列来标记要删除的行。

我想出了下面的方法来标记每个 ID 中的第一个日期行(排序后),但我无法弄清楚如何继续我的标志直到并包括第一行值 > 0:

df['flag'] = np.where((df.date == df.groupby('id')['date'].transform('flag')),1,0)

这让我:

id  date        value   flag
114 2016-01-01 0 1
114 2016-02-01 0 0
114 2016-03-01 200 0
114 2016-04-01 300 0
114 2016-05-01 100 0
220 2016-01-01 0 1
220 2016-02-01 0 0
220 2016-03-01 0 0
220 2016-04-01 0 0
220 2016-05-01 400 0
220 2016-06-01 200 0

但最终结果应该是:

id  date        value   flag
114 2016-01-01 0 1
114 2016-02-01 0 1
114 2016-03-01 200 1
114 2016-04-01 300 0
114 2016-05-01 100 0
220 2016-01-01 0 1
220 2016-02-01 0 1
220 2016-03-01 0 1
220 2016-04-01 0 1
220 2016-05-01 400 1
220 2016-06-01 200 0

最佳答案

您可以在不创建中间体的情况下实现这一目标 flag变量

假设您的数据如下所示:

     id       date  value
0 114 2016-01-01 0
1 114 2016-02-01 100
2 114 2016-03-01 200
3 114 2016-04-01 300
4 115 2016-01-01 0
5 115 2016-02-01 0
6 115 2016-03-01 100
7 115 2016-04-01 200
8 116 2016-01-01 100
9 116 2016-02-01 0 <-- notice the 0 value in the middle here
10 116 2016-03-01 330
11 116 2016-04-01 400

方法一

此方法假定所有 0 值都是不需要的,并且每个 id 中的第一个实际值组将以 0 开头。

我们所做的只是删除所有的零,然后 groupby id并简单地删除第一行数据。这具有删除第一个实际行及其之前的所有内容(假定为 0)的效果

df1 = df[df['value'] > 0]
df1.sort_values('date').groupby('id', group_keys=False).apply(lambda g: g.iloc[1:])

id date value
0 114 2016-03-01 200
1 114 2016-04-01 300
2 115 2016-04-01 200
3 116 2016-03-01 330
4 116 2016-04-01 400

方法二

如果每个 id 中间有零怎么办?组(如上面数据中的第 9 行)?

从您的问题中不清楚您在这种情况下想要做什么。按照你的描述,我假设你想要发生的是找到第一行(第 8 行),删除它和之前的所有内容(在这种情况下没有以前的数据),并单独留下 0

这里的关键是使用first_valid_index()获取非 NA/null 的第一行数据,并将其用作 .iloc 中的索引

def remove_prev(g):
out = g.replace({0: np.nan}).reset_index(drop=True)
return out.iloc[out['value'].first_valid_index()+1:].fillna(0)

df.groupby('id', group_keys=False).apply(remove_prev).reset_index(drop=True)

id date value
0 114.0 2016-03-01 200.0
1 114.0 2016-04-01 300.0
2 115.0 2016-04-01 200.0
3 116.0 2016-02-01 0.0
4 116.0 2016-03-01 330.0
5 116.0 2016-04-01 400.0

标记方法

如果你真的想设置一个标志变量,你可以再次使用first_valid_index()确定要设置的行 flag=1 :

def flag_prev(g):
out = g.replace({0: np.nan})
out.loc[:out['value'].first_valid_index(), 'flag'] = 1
return out.fillna(0)

df.groupby('id', group_keys=False).apply(flag_prev).reset_index(drop=True)

id date value flag
0 114.0 2016-01-01 0.0 1.0
1 114.0 2016-02-01 100.0 1.0
2 114.0 2016-03-01 200.0 0.0
3 114.0 2016-04-01 300.0 0.0
4 115.0 2016-01-01 0.0 1.0
5 115.0 2016-02-01 0.0 1.0
6 115.0 2016-03-01 100.0 1.0
7 115.0 2016-04-01 200.0 0.0
8 116.0 2016-01-01 100.0 1.0
9 116.0 2016-02-01 0.0 0.0
10 116.0 2016-03-01 330.0 0.0
11 116.0 2016-04-01 400.0 0.0

关于python - 如何按 ID 分组并用非空值标记第一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56863116/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com