我有以下数据框:
df = pd.DataFrame({'id': ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c','c','c'], 'cumsum': [1, 3, 6, 9, 10, 4, 9, 11, 13, 5, 8, 19]})
id cumsum
0 a 1
1 a 3
2 a 6
3 a 9
4 a 10
5 b 4
6 b 9
7 b 11
8 b 13
9 c 5
10 c 8
11 c 19
我想获得一个包含类别的新列,对于特定的输入,对于每个 id
,它将取最接近的大于(或等于)值作为第一个类别。
例如:
input = 8
期望输出:
id cumsum category
0 a 1 0
1 a 3 0
2 a 6 0
3 a 9 0
4 a 10 1
5 b 4 0
6 b 10 0
7 b 11 1
8 b 13 1
9 c 5 0
10 c 8 0
11 c 19 1
答案 0 :(得分:1)
您可以通过 GroupBy.first
输入并通过 Series.ge
过滤得到第一个值大于等于,然后通过 Series.gt
与 Id
比较 Series.map
映射值最后将掩码转换为整数:
val = 8
s = df[df['cumsum'].ge(val)].groupby('id')['cumsum'].first()
df['category'] = df['cumsum'].gt(df['id'].map(s)).astype(int)
print (df)
id cumsum category
0 a 1 0
1 a 3 0
2 a 6 0
3 a 9 0
4 a 10 1
5 b 4 0
6 b 9 0
7 b 11 1
8 b 13 1
9 c 5 0
10 c 8 0
11 c 19 1
另一个想法是将 Series.where
与 GroupBy.transform
结合使用:
val = 8
s1 = df['cumsum'].where(df['cumsum'].ge(val)).groupby(df['id']).transform('min')
#alternative
s1 = df['cumsum'].where(df['cumsum'].ge(val)).groupby(df['id']).transform('first')
df['category'] = df['cumsum'].gt(s1).astype(int)