복붙노트

[PYTHON] Python은 선형 보간법을 사용하여 불규칙한 시계열을 정규화합니다.

PYTHON

Python은 선형 보간법을 사용하여 불규칙한 시계열을 정규화합니다.

나는 다음과 같은 팬더에 시계열을 가지고 있습니다.

                     Values
1992-08-27 07:46:48    28.0  
1992-08-27 08:00:48    28.2  
1992-08-27 08:33:48    28.4  
1992-08-27 08:43:48    28.8  
1992-08-27 08:48:48    29.0  
1992-08-27 08:51:48    29.2  
1992-08-27 08:53:48    29.6  
1992-08-27 08:56:48    29.8  
1992-08-27 09:03:48    30.0

값을 선형 보간 한 15 분의 시간 간격으로 정규 시간 계열로 리샘플링하고 싶습니다. 기본적으로 나는 얻고 싶다 :

                     Values
1992-08-27 08:00:00    28.2  
1992-08-27 08:15:00    28.3  
1992-08-27 08:30:00    28.4  
1992-08-27 08:45:00    28.8  
1992-08-27 09:00:00    29.9

그러나 resample 메서드 (df.resample ( '15Min'))를 사용하여 Pandas에서 얻습니다.

                     Values
1992-08-27 08:00:00   28.20  
1992-08-27 08:15:00     NaN  
1992-08-27 08:30:00   28.60  
1992-08-27 08:45:00   29.40  
1992-08-27 09:00:00   30.00  

나는 '방법'과 'fill_method'매개 변수를 사용하여 resample 메서드를 시도했지만 원하는 결과를 얻지 못했습니다. 잘못된 방법을 사용하고 있습니까?

나는 이것이 꽤 간단한 질의라고 생각하지만, 나는 잠시 동안 웹을 수색했으며 대답을 찾을 수 없었다.

내가 얻을 수있는 도움에 미리 감사드립니다.

해결법

  1. ==============================

    1.약간의 작업이 필요하지만 이것을 시도하십시오. 기본 아이디어는 각각의 재 샘플 지점에 가장 가까운 두 개의 시간 소인을 찾고 보간하는 것입니다. np.searchsorted는 리샘플링 포인트에 가장 가까운 날짜를 찾는 데 사용됩니다.

    약간의 작업이 필요하지만 이것을 시도하십시오. 기본 아이디어는 각각의 재 샘플 지점에 가장 가까운 두 개의 시간 소인을 찾고 보간하는 것입니다. np.searchsorted는 리샘플링 포인트에 가장 가까운 날짜를 찾는 데 사용됩니다.

    # empty frame with desired index
    rs = pd.DataFrame(index=df.resample('15min').iloc[1:].index)
    
    # array of indexes corresponding with closest timestamp after resample
    idx_after = np.searchsorted(df.index.values, rs.index.values)
    
    # values and timestamp before/after resample
    rs['after'] = df.loc[df.index[idx_after], 'Values'].values
    rs['before'] = df.loc[df.index[idx_after - 1], 'Values'].values
    rs['after_time'] = df.index[idx_after]
    rs['before_time'] = df.index[idx_after - 1]
    
    #calculate new weighted value
    rs['span'] = (rs['after_time'] - rs['before_time'])
    rs['after_weight'] = (rs['after_time'] - rs.index) / rs['span']
    # I got errors here unless I turn the index to a series
    rs['before_weight'] = (pd.Series(data=rs.index, index=rs.index) - rs['before_time']) / rs['span']
    
    rs['Values'] = rs.eval('before * before_weight + after * after_weight')
    

    그 모든 후, 바라건대 올바른 대답 :

    In [161]: rs['Values']
    Out[161]: 
    1992-08-27 08:00:00    28.011429
    1992-08-27 08:15:00    28.313939
    1992-08-27 08:30:00    28.223030
    1992-08-27 08:45:00    28.952000
    1992-08-27 09:00:00    29.908571
    Freq: 15T, Name: Values, dtype: float64
    
  2. ==============================

    2.흔적을 가지고 이것을 할 수 있습니다. 먼저 사전과 같이 불규칙한 측정으로 TimeSeries를 만듭니다.

    흔적을 가지고 이것을 할 수 있습니다. 먼저 사전과 같이 불규칙한 측정으로 TimeSeries를 만듭니다.

    ts = traces.TimeSeries([
        (datetime(1992, 8, 27, 7, 46, 48), 28.0),
        (datetime(1992, 8, 27, 8, 0, 48), 28.2),
        ...
        (datetime(1992, 8, 27, 9, 3, 48), 30.0),
    ])
    

    그런 다음 샘플 방법을 사용하여 정규화합니다.

    ts.sample(
        sampling_period=timedelta(minutes=15),
        start=datetime(1992, 8, 27, 8),
        end=datetime(1992, 8, 27, 9),
        interpolate='linear',
    )
    

    회색 음영 점이 원래 데이터이고 오렌지색은 선형 보간법이 적용된 정규화 버전 인 다음 정규화 버전이 생성됩니다.

    보간 된 값은 다음과 같습니다.

    1992-08-27 08:00:00    28.189 
    1992-08-27 08:15:00    28.286  
    1992-08-27 08:30:00    28.377
    1992-08-27 08:45:00    28.848
    1992-08-27 09:00:00    29.891
    
  3. ==============================

    3.@mstringer가 얻는 결과는 팬더에서만 얻을 수 있습니다. 트릭은 먼저 중간 값 (.resample ( 's'). interpolate ())을 채우기 위해 보간법을 사용하여 초 단위로 다시 샘플링 한 다음 15 분 단위로 샘플을 업 샘플링합니다 (.resample ( '15T'). asfreq )).

    @mstringer가 얻는 결과는 팬더에서만 얻을 수 있습니다. 트릭은 먼저 중간 값 (.resample ( 's'). interpolate ())을 채우기 위해 보간법을 사용하여 초 단위로 다시 샘플링 한 다음 15 분 단위로 샘플을 업 샘플링합니다 (.resample ( '15T'). asfreq )).

    import io
    import pandas as pd
    
    data = io.StringIO('''\
    Values
    1992-08-27 07:46:48,28.0  
    1992-08-27 08:00:48,28.2  
    1992-08-27 08:33:48,28.4  
    1992-08-27 08:43:48,28.8  
    1992-08-27 08:48:48,29.0  
    1992-08-27 08:51:48,29.2  
    1992-08-27 08:53:48,29.6  
    1992-08-27 08:56:48,29.8  
    1992-08-27 09:03:48,30.0
    ''')
    s = pd.read_csv(data, squeeze=True)
    s.index = pd.to_datetime(s.index)
    
    res = s.resample('s').interpolate().resample('15T').asfreq().dropna()
    print(res)
    

    산출:

    1992-08-27 08:00:00    28.188571
    1992-08-27 08:15:00    28.286061
    1992-08-27 08:30:00    28.376970
    1992-08-27 08:45:00    28.848000
    1992-08-27 09:00:00    29.891429
    Freq: 15T, Name: Values, dtype: float64
    
  4. ==============================

    4.최근에는 불균일하게 샘플링 된 가속 데이터를 리샘플링해야했습니다. 일반적으로 정확한 주파수로 샘플링되었지만 간헐적으로 지연이 축적되었습니다.

    최근에는 불균일하게 샘플링 된 가속 데이터를 리샘플링해야했습니다. 일반적으로 정확한 주파수로 샘플링되었지만 간헐적으로 지연이 축적되었습니다.

    이 질문을 발견하고 mstringer와 Alberto Garcia-Rabosco의 답변을 순수한 팬더와 numpy를 사용하여 조합했습니다. 이 방법은 원하는 주파수에서 새 인덱스를 만든 다음 더 높은 주파수에서 보간하는 간헐적 인 단계없이 보간합니다.

    # from Alberto Garcia-Rabosco above
    import io
    import pandas as pd
    
    data = io.StringIO('''\
    Values
    1992-08-27 07:46:48,28.0  
    1992-08-27 08:00:48,28.2  
    1992-08-27 08:33:48,28.4  
    1992-08-27 08:43:48,28.8  
    1992-08-27 08:48:48,29.0  
    1992-08-27 08:51:48,29.2  
    1992-08-27 08:53:48,29.6  
    1992-08-27 08:56:48,29.8  
    1992-08-27 09:03:48,30.0
    ''')
    s = pd.read_csv(data, squeeze=True)
    s.index = pd.to_datetime(s.index)
    

    보간 작업을 수행하는 코드 :

    import numpy as np
    # create the new index and a new series full of NaNs
    new_index = pd.DatetimeIndex(start='1992-08-27 08:00:00', 
        freq='15 min', periods=5, yearfirst=True)
    new_series = pd.Series(np.nan, index=new_index)
    
    # concat the old and new series and remove duplicates (if any) 
    comb_series = pd.concat([s, new_series])
    comb_series = comb_series[~comb_series.index.duplicated(keep='first')]
    
    # interpolate to fill the NaNs
    comb_series.interpolate(method='time', inplace=True)
    

    산출:

    >>> print(comb_series[new_index])
    1992-08-27 08:00:00    28.188571
    1992-08-27 08:15:00    28.286061
    1992-08-27 08:30:00    28.376970
    1992-08-27 08:45:00    28.848000
    1992-08-27 09:00:00    29.891429
    Freq: 15T, dtype: float64
    

    앞에서와 같이 scipy가 지원하는 보간 방법을 사용할 수 있으며이 기술은 DataFrames에서도 작동합니다 (원래는이 방법을 사용했습니다). 마지막으로, interpolate는 인덱스의 시간 정보를 무시하고 비 균일하게 이격 된 데이터에서는 작동하지 않는 '선형'방법으로 기본 설정됩니다.

  5. from https://stackoverflow.com/questions/25234941/python-regularise-irregular-time-series-with-linear-interpolation by cc-by-sa and MIT license