首页 > 解决方案 > 如何按 ID 分组并用非空值标记第一行?

问题描述

在 aID中,我需要删除带有 a 的第一行value > 0和它之前的所有行,数据框中带有有序的日期列。我认为最简单的方法是创建一个新flag列来标记这些行以进行删除。

我想出了下面标记每个日期中的第一个日期行ID(排序后),但我无法弄清楚如何继续我的标志并包括第一行value > 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

标签: pythonpandas

解决方案


  1. 首先按升序排序 id 和日期
  2. 然后在第一个非零值用 Id 填充标志 1
  3. 将标志中的 0 替换为 nan
  4. bfill 与 group by 并转换
  5. 最后用 0 替换 Nan
df = pd.DataFrame(data={"id": [114, 114, 114, 114, 114, 220, 220, 220, 220, 220, 220],
                        "date": ['2016-01-01', '2016-02-01', '2016-03-01', '2016-04-01', '2016-05-01',
                                 '2016-01-01', '2016-02-01', '2016-03-01', '2016-04-01', '2016-05-01', '2016-06-01'],
                        'value': [0, 0, 200, 300, 100, 0, 0, 0, 0, 400, 200]})

df.sort_values(by=['id', 'date'], ascending=[True, True], inplace=True)
df['flag'] = 0
df.loc[df['value'].ne(0).groupby(df['id']).idxmax(),'flag']=1
df['flag'].replace({0:np.nan},inplace=True)

df['flag'] = df.groupby(['id'],as_index=False)['flag'].transform(pd.Series.bfill)
df['flag'].fillna(0,inplace=True)
print(df)
  id        date      value  flag
0   114  2016-01-01      0   1.0
1   114  2016-02-01      0   1.0
2   114  2016-03-01    200   1.0
3   114  2016-04-01    300   0.0
4   114  2016-05-01    100   0.0
5   220  2016-01-01      0   1.0
6   220  2016-02-01      0   1.0
7   220  2016-03-01      0   1.0
8   220  2016-04-01      0   1.0
9   220  2016-05-01    400   1.0
10  220  2016-06-01    200   0.0

我希望它能解决你的问题


推荐阅读