2016-07-29 83 views
2

我有下面的数据帧,我试图用一个数字来标记整个块,这个数字是基于类列中到目前为止已经看到了多少个类似的块。连续的类别值赋予相同的编号。如果稍后出现相同的等级块,则数字将递增。如果出现了一些新的等级块,则将其初始化为1在熊猫中计数重复的块

df = DataFrame(zip(range(10,30), range(20)), columns = ['a','b']) 
df['Class'] = [np.nan, np.nan, np.nan, np.nan, 'a', 'a', 'a', 'a', np.nan, np.nan,'a', 'a', 'a', 'a', 'a', np.nan, np.nan, 'b', 'b','b'] 

    a b Class 
0 10 0 NaN 
1 11 1 NaN 
2 12 2 NaN 
3 13 3 NaN 
4 14 4  a 
5 15 5  a 
6 16 6  a 
7 17 7  a 
8 18 8 NaN 
9 19 9 NaN 
10 20 10  a 
11 21 11  a 
12 22 12  a 
13 23 13  a 
14 24 14  a 
15 25 15 NaN 
16 26 16 NaN 
17 27 17  b 
18 28 18  b 
19 29 19  b 

样本输出看起来是这样的:

a b Class block_encounter_no 
0 10 0 NaN NaN 
1 11 1 NaN NaN 
2 12 2 NaN NaN 
3 13 3 NaN NaN 
4 14 4 a 1 
5 15 5 a 1 
6 16 6 a 1 
7 17 7 a 1 
8 18 8 NaN NaN 
9 19 9 NaN NaN 
10 20 10 a 2 
11 21 11 a 2 
12 22 12 a 2 
13 23 13 a 2 
14 24 14 a 2 
15 25 15 NaN NaN 
16 26 16 NaN NaN 
17 27 17 b 1 
18 28 18 b 1 
19 29 19 b 1 

回答

2

解决方案与mask

df['block_encounter_no'] = (df.Class != df.Class.shift()).mask(df.Class.isnull()) 
           .groupby(df.Class).cumsum() 
print (df) 
    a b Class block_encounter_no 
0 10 0 NaN     NaN 
1 11 1 NaN     NaN 
2 12 2 NaN     NaN 
3 13 3 NaN     NaN 
4 14 4  a     1.0 
5 15 5  a     1.0 
6 16 6  a     1.0 
7 17 7  a     1.0 
8 18 8 NaN     NaN 
9 19 9 NaN     NaN 
10 20 10  a     2.0 
11 21 11  a     2.0 
12 22 12  a     2.0 
13 23 13  a     2.0 
14 24 14  a     2.0 
15 25 15 NaN     NaN 
16 26 16 NaN     NaN 
17 27 17  b     1.0 
18 28 18  b     1.0 
19 29 19  b     1.0 
+0

谢谢。但是最后的块应该以1开始,因为'b'块是新类。 – learner

+0

对不起。现在我编辑答案 - 通过'Class'添加groupby,所以解决方案可以被纠正。 – jezrael

0

这样做:

df['block_encounter_no'] = \ 
    np.where(df.Class.notnull(), 
      (df.Class.notnull() & (df.Class != df.Class.shift())).cumsum(), 
      np.nan) 

enter image description here

+0

谢谢。但是最后的块应该以1开始,因为'b'块是新类。 – learner