在熊猫群中获得连续几周最长的连胜纪录

时间:2019-02-14 20:21:07

标签: python pandas time-series

目前,我正在处理不同主题的每周数据,但可能会有一些漫长的条纹而没有数据,因此,我想做的就是保持每id个连续几周的最长条纹。我的数据如下:

id    week
1      8
1      15
1      60
1      61
1      62
2      10
2      11
2      12
2      13
2      25
2      26

我的预期输出是:

id    week
1      60
1      61
1      62
2      10
2      11
2      12
2      13

我有点接近,尝试在week == week.shift()+1时标记为1。问题在于这种方法不会标记连续出现的第一个事件,而且我也不能过滤最长的一次:

df.loc[ (df['id'] == df['id'].shift())&(df['week'] == df['week'].shift()+1),'streak']=1

根据我的示例,这将带来以下结果:

id    week  streak
1      8     nan
1      15    nan
1      60    nan
1      61    1
1      62    1
2      10    nan
2      11    1
2      12    1
2      13    1
2      25    nan
2      26    1

关于如何实现我想要的任何想法?

2 个答案:

答案 0 :(得分:4)

尝试一下:

df['consec'] = df.groupby(['id',df['week'].diff(-1).ne(-1).shift().bfill().cumsum()]).transform('count')

df[df.groupby('id')['consec'].transform('max') == df.consec]

输出:

   id  week  consec
2   1    60       3
3   1    61       3
4   1    62       3
5   2    10       4
6   2    11       4
7   2    12       4
8   2    13       4

答案 1 :(得分:1)

不如@ScottBoston简洁,但我喜欢这种方法

def max_streak(s):
  a = s.values    # Let's deal with an array

  # I need to know where the differences are not `1`.
  # Also, because I plan to use `diff` again, I'll wrap
  # the boolean array with `True` to make things cleaner
  b = np.concatenate([[True], np.diff(a) != 1, [True]])

  # Tell the locations of the breaks in streak
  c = np.flatnonzero(b)

  # `diff` again tells me the length of the streaks
  d = np.diff(c)

  # `argmax` will tell me the location of the largest streak
  e = d.argmax()

  return c[e], d[e]

def make_thing(df):
  start, length = max_streak(df.week)
  return df.iloc[start:start + length].assign(consec=length)

pd.concat([
  make_thing(g) for _, g in df.groupby('id')    
])

   id  week  consec
2   1    60       3
3   1    61       3
4   1    62       3
5   2    10       4
6   2    11       4
7   2    12       4
8   2    13       4