LoginSignup
24
31

More than 5 years have passed since last update.

pandasで連続値をカウントする

Posted at

昨日書いた処理ににていますが、グループごとに連続する値をカウントしてみたいという要件があったとき、pandasには一発でやる機能がありません。
どのようにするか、stack overflowに答えがありましたが、2次的解説。

df = pd.DataFrame({'group' : [1,1,2,3,3,3,3,2,2,4,4,4] , 'value' : [1,2,1,1,3,2,4,2,1,3,2,1]} )

    group  value
0       1      1
1       1      2
2       2      1
3       3      1
4       3      3
5       3      2
6       3      4
7       2      2
8       2      1
9       4      3
10      4      2
11      4      1

cumcountじゃね?

こういうデータに対して、cumcount()を使うと以下のようになってしまいます。

df['new'] = df.groupby('group').cumcount()

    group  value  new
0       1      1    0
1       1      2    1
2       2      1    0
3       3      1    0
4       3      3    1
5       3      2    2
6       3      4    3
7       2      2    1
8       2      1    2
9       4      3    0
10      4      2    1
11      4      1    2

これでいい場合もあると思いますが、group2を扱う際、連続するという条件を加味すると、これではまずいことがわかります。

ちょっと気持ち悪いけど

so(Counting consecutive positive value in Python array)に書いてあったのは、以下のようにshiftとcumsumを使う方法です。ちょっと回りくどい気もしますが、わかりやすいです。

例はarrayでという質問でしたが、この回答はpandas DataFrameかSeriesに対して有効です。
簡単にいうと、シーケンスの変わり目にフラグを立てて、cumsomで階段状の累積インデックスを振っていきます。これで元のグループ(要素)とは関係なく連続値を再グループ化できますので、groupbyしてcumcount()で終わり。

y = df['group']
df['new'] = y.groupby((y != y.shift()).cumsum()).cumcount() + 1

    group  value  new
0       1      1    1
1       1      2    2
2       2      1    1
3       3      1    1
4       3      3    2
5       3      2    3
6       3      4    4
7       2      2    1
8       2      1    2
9       4      3    1
10      4      2    2
11      4      1    3

groupbyする前にグループ化したりとか、少々二度手間感がありますが、そもそもやろうとしていることが違うので、そんなに無駄ではないでしょうね。

24
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
31