날짜와 시간에 러그 특징 량 만들기 (날짜 시프트 및 집계)

테이블 데이터의 시계열 예측은 종종 러그 특징 (shift & rolling)을 만드는 것입니다.
지금까지는 단순히 행 수로 이동해야하는 경우 만 처리했지만 날짜로 이동하여 날짜로 집계하는 수요가 나왔습니다.
이것이 의외로 고생했기 때문에 메모로 남겨 둡니다.

다음 데이터를 예로 들어 설명합니다.
df = pd.DataFrame({
        "date": ["2021-04-01 10:04", "2021-04-01 12:03", "2021-04-02 14:40", "2021-04-03 2:01"
                , "2021-04-05 5:02", "2021-04-07 1:16", "2021-04-10 11:20", "2021-04-14 23:30"],
        "target": [1,5,7,2,3,7,9,3],
})
df["date"]=pd.to_datetime(df["date"])



지금까지 자주 사용해 온 것은 df["target_shift_rows"]=df["target"].shift(2).rolling(3).mean()와 같은 행 단위로 처리되었습니다.
행별 시프트이기 때문에 색인은 공통이며 대체가 간단합니다.

그러나 여기에서하고 싶은 것은 2 일 교대, 3 일 집계입니다.

1. 날짜별로 이동하여 날짜별로 집계
shift_rolling = df.set_index("date").shift(freq="2D").rolling("3D")[["target"]].mean()


  • index를 날짜로 설정하면 .shift(freq="2D")로 이틀 이동할 수 있습니다.
  • 일반 행 이동의 이미지와 달리 단순히 날짜가 2 일 벗어날뿐
  • 사전에 pd.Timedelta(days=2)를 그려 놓아도 같은 것을 실현할 수 있다

  • .rolling("3D")에서 3일 단위로 집계 가능
  • 색인이 날짜 일 때만 가능
  • index가 날짜가 아닌 경우, .rolling("3D", on="date")와 같이 on로 지정도 가능


  • 2. 무리하게 병합한다
    이전 테이블을 원래 테이블에 병합하고 싶지만 날짜가 엉망이므로 정확히 일치하지 않으며 일반 병합에서는 아무 것도 없습니다.
    merge_asof이라는 함수를 사용하면이를 해결할 수 있습니다.
    df = pd.merge_asof(df, shift_rolling, on="date", direction="backward", suffixes=("","_shift"))
    


  • direction
  • "backward" : 뒤쪽에 가까운 값으로 병합
  • "forward" : 앞으로 가까운 값으로 병합
  • "nearest" : 가장 가까운 값으로 병합


  • 이 경우 미래 ​​정보를 참조하지 않도록 "backward"를 사용하십시오.

    See htps // 팬더 s. py였다. 오 rg / 팬더 s-도 cs / s 타 b ぇ / 레후 렌세 / 아피 / 팬더 s. 메르게_아소 f. HTML

    groupby에서 사용하고 싶다면



    사용자 ID 또는 제품 ID별로 날짜로 처리하고 싶다면 더 복잡해집니다.
    df = pd.DataFrame({
            "date": ["2021-04-01 10:04", "2021-04-01 12:03", "2021-04-02 14:40", "2021-04-03 2:01"
                    , "2021-04-05 5:02", "2021-04-07 1:16", "2021-04-10 11:20", "2021-04-14 23:30"],
            "group": ["a","a","b","a","b","a","b","b"],
            "target": [1,5,7,2,3,7,9,3],
    })
    df["date"]=pd.to_datetime(df["date"])
    



    이번에는 그룹별로 1 일 쉬프트, 2 일 평균을 취하고 싶다.
    tmp = df.set_index("date").groupby("group")[["target"]].apply(
        lambda x: pd.merge_asof(pd.DataFrame(x.index), 
                                x.shift(freq="1D").rolling("2D").mean(),
                                on="date",
                                direction="backward",
                               )
    )
    


    pd.merge_asof가 여러 열의 병합을 지원하지 않기 때문에 미리 병합을 위해 이동 된 "date" 열을 원래 "date" 열로 합리적으로 병합합니다.
    추가 : by라는 인수로 on 앞에 일반적으로 병합 할 항목을 설정할 수있는 것 같습니다.
    df = df.merge(tmp, on=["group","date"], suffixes=("","_shift"))
    



    마지막으로 여러 열로 병합하면 괜찮습니다.

    요약


  • pd.merge_asof의 존재를 알고 있는지 여부
  • 좋은 웹페이지 즐겨찾기