Python Pandas-基于前一行中的值的唯一ID
我正在为一组行创建一个ID,其中ID基于前一行中的值。我目前已经使用for循环完成了这项工作,但是由于行太多,所以速度非常慢。有没有更简单的方法 具体来说,当类别和值不等于前一行的类别和值时,我将创建一个新的唯一IDPython Pandas-基于前一行中的值的唯一ID,python,pandas,Python,Pandas,我正在为一组行创建一个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/201
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
下面的方法不一定比循环快,但至少它没有任何显式循环。首先获取下一个值和上一个值之间的差值。值更改时,差值不等于零:
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
不幸的是,类别并不是严格意义上的单一字符。问题应该更清楚。更新问题以反映。您可以使用原始的
shift
模式而不是diff技巧,例如keys=df[[“类别”,“值”];(keys!=keys.shift()).any(axis=1.cumsum()
@DSM-Sure。请随意将其作为答案发布。