我有一个pandas数据帧,其中一个列描述了一个整数时间索引,我想添加一个列来存储一行是否是streak的一部分,以及streak有多长。例如,给定time列,我想计算一个streak列,如下所示
time streak
0 3
1 3
2 3
4 2
5 2
5 2
9 1
11 1
11 1前三条线是连续三条线的一部分,因为索引0,1,2是连续的。下面三行的条纹为2,因为索引4,5也是连续的;索引5是重复的,但在确定条纹的长度时不应计入索引5。最后,最后三行与其他行不相邻,因此它们的条纹为1。请注意,有时多行可以具有相同的time。我需要以时间为单位计算条纹的长度,以便多个条目不会影响条纹的长度,并且具有相同时间索引的线具有相同的条纹长度。请记住,其他列(未显示)存储在数据帧中。
如何获取该值?我尝试过使用groupby、shift和类似的函数,但并没有走得太远。
编辑:对不起,我忘记指定有时time索引可以重复。我对这个问题进行了扩展,以将这一点考虑在内。
发布于 2018-09-17 22:58:58
使用diff查找是否继续(等于1 ),然后使用条件匹配的cumsum,然后使用groupby + transform szie
s=df.time.diff().fillna(1).ne(1).cumsum()
s.groupby(s).transform('size')
Out[396]:
0 3
1 3
2 3
3 2
4 2
5 1
6 1
Name: time, dtype: int32发布于 2018-09-17 23:09:11
与温的答案非常相似,只是使用value_counts,我觉得这稍微更流行一点。
time = pd.Series([0, 1, 2, 4, 5, 9, 11])
# Give each row a streak id by incrementing whenever the difference isn't 1
streak = (time.diff() != 1).cumsum()
# Maps each id to the number of times the id occurs
result = streak.map(streak.value_counts())
print(result)
Out:
0 3
1 3
2 3
3 2
4 2
5 1
6 1编辑:这里有一个解决方案,以迎合添加到问题中的新情况,其中可能存在重复时间。请注意,我们使用diff > 1来查找新的条纹;这是使用时间是递增的(不一定是严格的)整数的假设。可能的重复只是意味着我们必须在计算出用于映射的streak id计数之前执行drop_duplicates。
time = pd.Series([0, 1, 2, 4, 5, 5, 9, 11, 11])
result = (time.diff() > 1).cumsum().map(
(time.drop_duplicates().diff() > 1).cumsum().value_counts()
)
print(result)
Out:
0 3
1 3
2 3
3 2
4 2
5 2
6 1
7 1
8 1https://stackoverflow.com/questions/52370489
复制相似问题