Python-在Pandas Dataframe中查找最长的连续运行

时间:2018-08-09 06:38:04

标签: python pandas

我有一个pandas数据框,它具有以下变量:周,产品代码,约束标志(0或1表示产品供应是否受到限制)。

Week    Product_Code    Constraint_Flag
1           A                1
1           B                0
2           A                0
2           B                1
3           A                0
3           B                0
4           A                0
4           B                0
5           A                1
5           B                0    

我想找到供应不受限制的最长时间段,即每个产品代码的最长字符串0s。因此,对于产品A,我想知道最长的字符串在第3周开始,持续了2周,对于产品B,最长的字符串在第3周开始,持续了3周。

我该怎么做?

1 个答案:

答案 0 :(得分:2)

使用this solution来查找最长0个周期,然后使用第一个和最后一个聚合进行过滤:

m  = np.concatenate(( [True], df['Constraint_Flag'] != 0, [True] ))
ss = np.flatnonzero(m[1:] != m[:-1]).reshape(-1,2)
s, e = ss[(ss[:,1] - ss[:,0]).argmax()]
pos = df.columns.get_loc('Week')
print (s,e)
4 8

print (df.iloc[s:e])
   Week Product_Code  Constraint_Flag
4     3            A                0
5     3            B                0
6     4            A                0
7     4            B                0

df = df.iloc[s:e].groupby('Product_Code')['Week'].agg(['first','last'])
print (df)
              first  last
Product_Code             
A                 3     4
B                 3     4

但如果需要按组进行比较:

def f(x):
    print (x)
    m  = np.concatenate(( [True], x['Constraint_Flag'] != 0, [True] ))
    ss = np.flatnonzero(m[1:] != m[:-1]).reshape(-1,2)
    s, e = ss[(ss[:,1] - ss[:,0]).argmax()]
    pos = x.columns.get_loc('Week')
    c = ['start','end']
    return pd.Series([x.iat[s, pos], x.iat[e-1, pos]], index=c)

   Week Product_Code  Constraint_Flag
0     1            A                1
2     2            A                0
4     3            A                0
6     4            A                0
8     5            A                1
   Week Product_Code  Constraint_Flag
1     1            B                0
3     2            B                1
5     3            B                0
7     4            B                0
9     5            B                0

df = df.groupby('Product_Code').apply(f)
print (df)
              start  end
Product_Code            
A                 2    4
B                 3    5