2015-10-14 17 views
3

我想創建一個列(「consec」),它將保持連續值在另一個(「二進制」)中的運行計數而不使用循環。這是所期望的結果將是什麼樣子:python熊貓 - 創建一個保持連續值運行計數的列

. binary consec 
1  0  0 
2  1  1 
3  1  2 
4  1  3 
5  1  4 
5  0  0 
6  1  1 
7  1  2 
8  0  0 

然而,這...

df['consec'][df['binary']==1] = df['consec'].shift(1) + df['binary'] 

結果在這...

. binary consec 
0  1  NaN 
1  1  1 
2  1  1 
3  0  0 
4  1  1 
5  0  0 
6  1  1 
7  1  1 
8  1  1 
9  0  0 

我看其他的帖子在使用分組或排序,但不幸的是,我不明白這可以爲我工作。在此先感謝您的幫助。

+0

你說‘連續’,而是0和1是不同的,你仍然增加櫃檯。所以感覺更像是你想在每個零點重置計數器。你想要發生什麼,連續有兩個零? – DSM

+0

好點 - 差的描述,我確實想在每個零點重置計數器。因此df ['binary']中的連續0會在df ['consec']中生成0。 – MJS

回答

10

可以使用比較-cumsum-GROUPBY模式(我真的需要避過對方寫下的文件),與最終cumcount

>>> df = pd.DataFrame({"binary": [0,1,1,1,0,0,1,1,0]}) 
>>> df["consec"] = df["binary"].groupby((df["binary"] == 0).cumsum()).cumcount() 
>>> df 
    binary consec 
0  0  0 
1  1  1 
2  1  2 
3  1  3 
4  0  0 
5  0  0 
6  1  1 
7  1  2 
8  0  0 

這工作,因爲首先我們得到我們想要重置計數器的位置:

>>> (df["binary"] == 0) 
0  True 
1 False 
2 False 
3 False 
4  True 
5  True 
6 False 
7 False 
8  True 
Name: binary, dtype: bool 

這些累計總和給了我們一個di每個組fferent ID:

>>> (df["binary"] == 0).cumsum() 
0 1 
1 1 
2 1 
3 1 
4 2 
5 3 
6 3 
7 3 
8 4 
Name: binary, dtype: int64 

,然後我們可以通過這個來groupby和使用cumcount獲得各組的增加指數。

+0

這將是一個很好的補充文件,可能在食譜。 – Alexander

+0

頭腦風暴。是否有任何理由,如果泛[[A]] = df,這將不適用於面板的數據框? – MJS

+0

無視帝斯曼 - 想通了。謝謝你的幫助! – MJS

2

對於那些誰在這裏結束了尋找答案的「誤解」的版本: 要重置在二進制列的每個變化計數,使consec沒有「保持運行計數連續值」,下面似乎工作:

df["consec2"] = df["binary"].groupby((df["binary"] <> df["binary"].shift()).cumsum()).cumcount() 

enter image description here