特定の値のギャップを数える – 任意の要素間のカウント

Pandas: count gaps for specific values – StackOverflow

各列で求めるインターバルが違うので,indexをリネームしようと思うとループを回すしか無い.
値が欲しいだけなら,numpyを用いてベクトル処理が可能.

import io
import pandas as pd        
import numpy as np


strings = """1 A
2 A
3 B
4 A
5 C
6 B
7 C
8 A
9 B"""
s = pd.read_csv(io.StringIO(strings), sep='\s+', 
                header=None, index_col=0, squeeze=True)
print(s)

for k in s.unique():
    idx = s.index[s.eq(k)] - 1
    s_ = s[idx.min():idx.max()]
    g = s_.eq(k).cumsum()
    ind = s_.index.groupby(g)
    res = s_.ne(k).groupby(g).apply(np.count_nonzero)
    res.index = [f'{x[0]}-{x[-1]+1}' for x in ind.values()]
    print(res)
0
1    A
2    A
3    B
4    A
5    C
6    B
7    C
8    A
9    B
Name: 1, dtype: object
1-2    0
2-4    1
4-8    3
Name: 1, dtype: int64
3-6    2
6-9    2
Name: 1, dtype: int64
5-7    1
Name: 1, dtype: int64

numpyベクトライズなソリューションを考えるなら,
任意の範囲で累積和(specified_cumsum)をとり,
0の間の数字だけをピックアップすれば良い.
最適化していないので,ぐちゃぐちゃだけど,こういう感じで.

def seq_cumsum_1d(a):
    arr = a.copy()
    ind = np.concatenate(([0], np.flatnonzero(np.diff(arr))+1))
    arr[ind[1:]] -= np.add.reduceat(arr, ind)[:-1]
    return arr.cumsum(0)


def func(s):
    a, b = s.factorize()
    u = np.arange(len(b))
    arr = (a != u[:, None]).astype(int)
    return arr


arr = func(s)
print(arr)
res = np.apply_along_axis(seq_cumsum_1d, 1, arr)
print(res)

a = (res==0).cumsum(1)
cond1 = a[:, :-1] != 0
cond2 = a[:, :-1] != a[:, 1:]
cond = np.logical_and(cond1, cond2)
b = np.column_stack((np.zeros(3, dtype=int), cond.cumsum(1)))
ind = np.diff(b).astype(bool)
print(res[:, :-1][ind])
[[0 0 1 0 1 1 1 0 1]
 [1 1 0 1 1 0 1 1 0]
 [1 1 1 1 0 1 0 1 1]]
[[0 0 1 0 1 2 3 0 1]
 [1 2 0 1 2 0 1 2 0]
 [1 2 3 4 0 1 0 1 2]]
[0 1 3 2 2 1]
カテゴリー: 未分類 パーマリンク

特定の値のギャップを数える – 任意の要素間のカウント への6件のフィードバック

  1. ピンバック: pandas.DataFrame.applyは(時空間効率の観点からは)使用するべきではない – 使用すべき明確な理由がない限りpandas.DataFrame.applyはリーズナブルチョイスになり得ない | 粉末@それは風のように

  2. ピンバック: pandas.DataFrame.applyは(時空間効率の観点からは)使用するべきではない – 使用すべき明確な理由がない限りpandas.DataFrame.applyはリーズナブルチョイスになり得ない | 粉末@それは風のように

  3. ピンバック: データフレーム各行の連続したゼロをカウント | 粉末@それは風のように (日記)

  4. ピンバック: データフレームの任意列における条件から降順の累積和を求める | 粉末@それは風のように (日記)

  5. ピンバック: pandasデータフレーム列内のNaNに基づいて累積和をリセット – 任意の条件に基づいた範囲で累積和を求める | 粉末@それは風のように (日記)

  6. ピンバック: データフレーム列内の連続した値の和(任意長の範囲で合計) | 粉末@それは風のように (日記)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください