あなたはTrue
秒のクラスタを識別するためにscipy.ndimage.label
を使用することができます。
In [102]: ts
Out[102]:
0.069347 False
0.131956 False
0.143948 False
0.224864 False
0.242640 True
0.372599 False
0.451989 False
0.462090 False
0.579956 True
0.588791 True
0.603638 False
0.625107 False
0.642565 False
0.708547 False
0.730239 False
0.741652 False
0.747126 True
0.783276 True
0.896705 True
0.942829 True
Name: keep, dtype: bool
In [103]: groups, nobs = ndimage.label(ts); groups
Out[103]: array([0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3], dtype=int32)
あなたがgroups
配列を持っていたら、あなたはgroupby/agg
を使用して、関連する時間を見つけることができます:
result = (df.loc[df['group'] != 0]
.groupby('group')['times']
.agg({'start':'first','end':'last'}))
例えば、
import numpy as np
import pandas as pd
import scipy.ndimage as ndimage
np.random.seed(2016)
def make_ts(N, ngroups):
times = np.random.random(N)
times = np.sort(times)
idx = np.sort(np.random.randint(N, size=(ngroups,)))
arr = np.zeros(N)
arr[idx] = 1
arr = arr.cumsum()
arr = (arr % 2).astype(bool)
ts = pd.Series(arr, index=times, name='keep')
return ts
def find_groups(ts):
groups, nobs = ndimage.label(ts)
df = pd.DataFrame({'times': ts.index, 'group': groups})
result = (df.loc[df['group'] != 0]
.groupby('group')['times']
.agg({'start':'first','end':'last'}))
return result
ts = make_ts(20, 5)
result = find_groups(ts)
は、あなたが使用できるリストのリストとして開始時刻と終了時刻を取得するには
start end
group
1 0.242640 0.242640
2 0.579956 0.588791
3 0.747126 0.942829
が得られます。
In [125]: result.values.tolist()
Out[125]:
[[0.24264034406127022, 0.24264034406127022],
[0.5799564094638113, 0.5887908182432907],
[0.747126, 0.9428288694956402]]
ndimage.label
を使用すると便利ですが、これを計算することも可能であることに注意してくださいなしscipy
:
def find_groups_without_scipy(ts):
df = pd.DataFrame({'times': ts.index, 'group': (ts.diff() == True).cumsum()})
result = (df.loc[df['group'] % 2 == 1]
.groupby('group')['times']
.agg({'start':'first','end':'last'}))
return result
ここでの主なアイデアは、 True
のクラスタのラベルは(ts.diff() == True).cumsum()
を使用します。 ts.diff() == True
はts.shift()^ts
と同じ結果を示しますが、少し速いです。 (すなわち、cumsum
を呼び出す)の累積和をとると、0と同等True
などの1に等しいとFalse
扱い、そうTrue
は、したがって、各クラスタが異なる数で標識されます1によって累積和増加に遭遇するたび:
In [111]: (ts.diff() == True).cumsum()
Out[111]:
0.069347 0
0.131956 0
0.143948 0
0.224864 0
0.242640 1
0.372599 2
0.451989 2
0.462090 2
0.579956 3
0.588791 3
0.603638 4
0.625107 4
0.642565 4
0.708547 4
0.730239 4
0.741652 4
0.747126 5
0.783276 5
0.896705 5
0.942829 5
Name: keep, dtype: int64
無関係の依存関係を導入するのではなく、自由にリソースを使用することができます。 –
答えに感謝します!しかし、あなたのコードは最初の要素に無関心ではないように見えますが、これは真または偽である可能性があります。 簡単な修正は、真であれば最初の行を結果に挿入することです(最後の行についても同様です) 助けてくれてありがとうございます! EDIT:実際には、エッジが上昇または下降しているかどうかを示す結果の最初の(最後の)要素の値を見ることができます。したがって、最初は実際には問題はありませんでした。 –