質問: やりたいことは以下になります。 IDごとに直近1年分の売上データがあり、直近nケ月の金額がn万円を連続して超える人が何人いるかカウントしたいと考えています。 例えば、直近3ケ月の金額が17万円を連続して超える人数(3ケ月の中で1ケ月でも17万円を下回る月がある人は含まれない)、16万円を連続して超える人数、15万円を超える人数、...1万円を超える人数とスタート地点の金額から1万円刻みで人数をカウントしたいです。 (上記例でいうと17万を連続して超える人は当然16万円を連続して超えることになるので、IDの重複は許すことにします) for文を使えば簡単にできると思うのですが、どのように記述すれば良いのかわからないのでご教示いただけますと幸いです。 ![画像の説明をここに入力](https://i.stack.imgur.com/5r4d1.png)
回答: 例えばこのようなデータを考えてみます * 横に月が並ぶ * 縦(行頭)が ID とする 連続した三ヶ月分の最小値を取り出し, 一定値を超えているかどうか 2月から 4月分までの場合, 4月が該当する月, という判断にします (つまり(どのようなデータであっても) 1月, 2月は件数ゼロ) ``` import pandas as pd import numpy as np # とりあえずランダムな値を実験用に用意 df = pd.DataFrame(np.random.randint(1000, 20000, (4, 12))) df.rename(columns=lambda v: f'{v+1}月', index=lambda v: f'ID_{v:03d}', inplace=True) display(df) # (とりあえず) 8000 以上の値の表示, 及び 件数の表示 b8k = df.rolling(3, axis=1).min() >= 8000 display(df[b8k].fillna('')) b8k.sum() ``` | | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ID_000 | 2261 | 8830 | 14073 | 15578 | 3376 | 4917 | 17502 | 7456 | 15905 | 1747 | 17220 | 3247 | | ID_001 | 11592 | 3769 | 4658 | 12233 | 16910 | 8890 | 8288 | 7854 | 10683 | 5842 | 4346 | 7808 | | ID_002 | 4803 | 9351 | 1450 | 17890 | 9665 | 19335 | 11165 | 10414 | 14457 | 14395 | 10539 | 13496 | | ID_003 | 12803 | 3727 | 7279 | 9647 | 17536 | 4401 | 16852 | 11295 | 14799 | 2446 | 12863 | 1393 | | | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | ID_000 | | | | 15578 | | | | | | | | | | ID_001 | | | | | | 8890 | 8288 | | | | | | | ID_002 | | | | | | 19335 | 11165 | 10414 | 14457 | 14395 | 10539 | 13496 | | ID_003 | | | | | | | | | 14799 | | | | 1月 0 2月 0 3月 0 4月 1 5月 0 6月 2 7月 2 8月 1 9月 2 10月 1 11月 1 12月 1 dtype: int64