Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

time_series_search: 조건이 유지되는 구간 찾기

foundryts.functions.time_series_search(
    predicate, labels=None, start=None, end=None, interval_values=None,
    before='nearest', internal='default', after='nearest',
    min_duration=None, max_duration=None
)

시계열 하나 이상에서 predicate가 참인 구간을 찾고 각 구간의 통계를 반환하는 함수를 만듭니다. 이 구간은 Quiver의 이벤트에 대응합니다. 관측값을 직접 검색하는 기능이며, 객체 속성으로 시계열 참조를 찾는 Search와 구분합니다.

검색과 통계 인수

인수형식기본값과 의미
predicatestr구간을 찾는 DSL 조건식
labelsstr 또는 List[str]입력 시계열의 별칭. 기본은 a, b부터 aa, ab 등으로 이어짐
startint, datetime 또는 strNone. 검색 시작 시각 포함. 기본 하한은 pandas.Timestamp.min
endint, datetime 또는 strNone. 검색 종료 시각 제외. 기본 상한은 pandas.Timestamp.max
interval_valuesstr구간 통계를 계산할 값의 DSL 식. 기본은 첫 입력 시계열
min_durationint, str 또는 datetime.timedeltaNone. 구간으로 인정할 최소 지속 시간
max_durationint, str 또는 datetime.timedeltaNone. 구간으로 인정할 최대 지속 시간

start 또는 end와 겹치는 구간은 전체 구간을 반환합니다. 검색 경계에 맞춰 구간을 잘라 반환하는 방식이 아니므로, 반환 구간의 시작이나 끝이 검색 범위를 벗어날 수 있습니다.

통계는 숫자형 값을 필요로 합니다. 범주형 시계열을 입력으로 사용하면 interval_values에 숫자형 결과를 만드는 식을 지정해야 합니다. 여러 입력 중 숫자형 시계열을 통계 대상으로 선택할 수도 있습니다.

보간 인수

인수형식기본 동작
beforestr 또는 List[str]NEAREST. 첫 관측 이전
internalstr 또는 List[str]default. 숫자형 LINEAR, 범주형 PREVIOUS
afterstr 또는 List[str]NEAREST. 마지막 관측 이후

목록으로 지정하면 입력 순서대로 전략을 적용합니다. 허용 전략은 interpolate, 조건 및 값 식은 dsl을 사용합니다.

반환 결과

반환한 요약 질의를 DataFrame으로 평가하면 구간마다 통계 한 행을 얻습니다. 다음은 가상 결과에서 사용하는 필드입니다. 다른 계산에 경계를 연결할 때는 평가한 DataFrame의 columns에서 실제 경계 열 이름을 확인하여 명시적으로 선택합니다.

열형식의미
start_timedatetime구간 시작, 포함
end_timedatetime구간 끝, 제외
countint구간의 관측 수
earliest_point.timestampdatetime첫 관측 시각
earliest_point.valuefloat첫 관측값
latest_point.timestampdatetime마지막 관측 시각
latest_point.valuefloat마지막 관측값
smallest_point.timestampdatetime최솟값 관측 시각
smallest_point.valuefloat최솟값
largest_point.timestampdatetime최댓값 관측 시각
largest_point.valuefloat최댓값
meanfloat관측값 평균
standard_deviationfloat관측값 표준편차
duration.secondsint지속 시간의 초 부분
duration.subsecond_nanosint지속 시간의 초 미만 나노초 부분

구간 경계로 Interval을 만들고 NodeCollection.map_intervals에 전달하면 각 구간을 별도 시계열로 나누어 계산할 수 있습니다.

가상 숫자형 입력

import foundryts.functions as F

discrete_series = F.points(
    (0, 1.0),
    (1, 2.0),
    (2, 2.0),
    (3, 3.0),
    (4, 5.0),
    (5, 6.0),
    (6, 4.0),
    (7, 2.0),
    (8, 6.0),
    (9, 7.0),
    (10, 8.0),
    (11, 10.0),
    (12, 11.0),
    name="discrete",
)

이후 표의 시각은 모두 Unix epoch 이후 나노초이며 각 구간의 duration.seconds는 0입니다. 괄호로 표시한 관측은 (시각 ns, 값)입니다.

짝수 값의 구간

even_search = F.time_series_search(
    predicate="discrete % 2 == 0",
    interval_values="discrete",
    labels="discrete",
)(discrete_series)
interval_df = even_search.to_pandas()
result_columns = list(interval_df.columns)

짝수 관측이 이어지는 구간은 세 개입니다.

start_time(ns)end_time(ns)포함 관측countduration.subsecond_nanosmeanstandard_deviation
13(1, 2), (2, 2)222.00.0
59(5, 6), (6, 4), (7, 2), (8, 6)444.51.658312
1012(10, 8), (11, 10)229.01.0

각 행의 끝점과 극값 정보는 다음과 같습니다.

구간 시작(ns)earliest_pointlatest_pointsmallest_pointlargest_point
1(1, 2.0)(2, 2.0)(2, 2.0)(2, 2.0)
5(5, 6.0)(8, 6.0)(7, 2.0)(8, 6.0)
10(10, 8.0)(11, 10.0)(10, 8.0)(11, 10.0)

구간은 그대로 두고 통계 값을 변환

doubled_values = F.time_series_search(
    predicate="discrete % 2 == 0",
    interval_values="discrete * 2",
    labels="discrete",
)(discrete_series)
doubled_df = doubled_values.to_pandas()

predicate는 그대로이므로 경계, 관측 수와 지속 시간은 같은 세 구간입니다. interval_values가 각 값을 두 배로 만든 뒤 통계를 계산합니다.

구간 시작(ns)meanstandard_deviationearliest_pointlatest_pointsmallest_pointlargest_point
14.00.0(1, 4.0)(2, 4.0)(2, 4.0)(2, 4.0)
59.03.316625(5, 12.0)(8, 12.0)(7, 4.0)(8, 12.0)
1018.02.0(10, 16.0)(11, 20.0)(10, 16.0)(11, 20.0)

지속 시간 조건

최소 3나노초를 요구하면 길이가 2인 첫 구간과 마지막 구간을 제외합니다.

minimum_duration = F.time_series_search(
    predicate="discrete % 2 == 0",
    interval_values="discrete",
    labels="discrete",
    min_duration="3ns",
)(discrete_series)
minimum_df = minimum_duration.to_pandas()

결과는 [5, 9) 한 구간이며 count=4, mean=4.5, standard_deviation=1.658312입니다. 끝점과 극값은 기본 검색의 해당 행과 같습니다.

최대 3나노초를 지정하면 길이가 4인 가운데 구간을 제외합니다.

maximum_duration = F.time_series_search(
    predicate="discrete % 2 == 0",
    interval_values="discrete",
    labels="discrete",
    max_duration="3ns",
)(discrete_series)
maximum_df = maximum_duration.to_pandas()

결과는 [1, 3)과 [10, 12)이며 각 행의 통계는 기본 검색과 같습니다.

범주형 조건으로 다른 시계열 분석

상태를 나타내는 가상 toggle 시계열을 추가합니다.

toggle_series = F.points(
    (0, "OFF"),
    (1, "ON"),
    (2, "OFF"),
    (3, "OFF"),
    (4, "ON"),
    (5, "ON"),
    (6, "ON"),
    (7, "OFF"),
    (8, "ON"),
    (9, "ON"),
    (10, "OFF"),
    (11, "OFF"),
    (12, "ON"),
    name="toggle",
)
cross_series = F.time_series_search(
    predicate='toggle == "ON"',
    interval_values="discrete",
    labels=["toggle", "discrete"],
)([toggle_series, discrete_series])
cross_series_df = cross_series.to_pandas()

첫 입력의 상태가 ON인 구간을 찾고 두 번째 숫자형 입력의 값으로 통계를 계산합니다. 가상 결과는 다음 네 구간입니다.

start_time(ns)end_time(ns)포함된 discrete 관측countduration.subsecond_nanosmeanstandard_deviation
12(1, 2)112.00.0
47(4, 5), (5, 6), (6, 4)335.00.816497
810(8, 6), (9, 7)226.50.5
1213(12, 11)1111.00.0
구간 시작(ns)earliest_pointlatest_pointsmallest_pointlargest_point
1(1, 2.0)(1, 2.0)(1, 2.0)(1, 2.0)
4(4, 5.0)(6, 4.0)(6, 4.0)(5, 6.0)
8(8, 6.0)(9, 7.0)(8, 6.0)(9, 7.0)
12(12, 11.0)(12, 11.0)(12, 11.0)(12, 11.0)