당신은 True
의의 클러스터를 식별하는 scipy.ndimage.label
을 사용할 수 있습니다 : 당신이 groups
배열이 있으면
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)
, 당신은 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)
In [125]: result.values.tolist()
Out[125]:
[[0.24264034406127022, 0.24264034406127022],
[0.5799564094638113, 0.5887908182432907],
[0.747126, 0.9428288694956402]]
이 ndimage.label
편리 사용하지만,이 계산하는 것도 가능 참고 :은
start end
group
1 0.242640 0.242640
2 0.579956 0.588791
3 0.747126 0.942829
당신이 사용할 수있는 목록의 목록으로 시작 시간과 종료 시간을 구하려면 산출 without 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 동등한 1 False
에 동등한 True
취급하므로마다 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
을
불필요한 종속성을 제공하는 대신 원하는대로 리소스를 사용하십시오. –
답해 주셔서 감사합니다! 그러나 코드가 첫 번째 요소에 대해 불가지론스러워 보이지는 않습니다.이 요소는 True 또는 False 일 수 있으므로 먼저 원하는 것과 반대 방향으로 끝냅니다. 쉬운 수정 프로그램은 첫 번째 행이 참이면 결과에 첫 번째 행을 삽입하는 것입니다 (마지막 행과 동일합니다) 어쨌든 도움을 주셔서 감사합니다! 편집 : 실제로 가장자리의 상승 또는 하강을 알리는 결과의 첫 번째 (및 마지막) 요소의 값을 볼 수 있으므로 처음에는 문제가 실제로 발생하지 않았습니다. –