我正在为一组行创建一个ID,其中该ID基于上一行中的值。我目前已经使用for循环完成了此操作,但是由于行太多,这非常慢。有更简单的方法吗?
具体来说,当类别和值与上一行的类别和值不相等时,我将创建一个新的唯一ID。
df = date category value
1/1/2018 A 0
1/2/2018 A 0
1/3/2018 A 1
1/4/2018 A 0
1/1/2018 AB 1
1/2/2018 AB 1
1/3/2018 AB 1
1/4/2018 ABC 0
df_out = date category value unique_id
1/1/2018 A 0 1
1/2/2018 A 0 1
1/3/2018 A 1 2
1/4/2018 A 0 3
1/1/2018 AB 1 4
1/2/2018 AB 1 4
1/3/2018 AB 1 4
1/4/2018 ABC 0 5
答案 0 :(得分:2)
以下方法不一定比循环快,但是至少它没有任何显式循环。首先计算下一个和上一个值之间的差。值更改时,差不等于零:
val_diff = df['value'].diff().fillna(0) != 0 # Boolean!
相同的技巧不适用于该类别,因为不能减去字符。获取所有唯一类别的列表,对其进行枚举,然后使用枚举值代替类别名称:
unique = df['category'].unique()
unique_mapping = {y:x for x,y in enumerate(unique)}
cat_diff = df['category'].replace(unique_mapping)\
.diff().fillna(0) != 0
当类别的值更改时,id会增加:
df['id'] = (val_diff | cat_diff).cumsum() + 1
df
# date category value id
#0 1/1/2018 A 0 1
#1 1/2/2018 A 0 1
#2 1/3/2018 A 1 2
#3 1/4/2018 A 0 3
#4 1/1/2018 B 1 4
#5 1/2/2018 B 1 4
#6 1/3/2018 B 1 4
#7 1/4/2018 B 0 5