83945


concatとjoinメソッドを利用することで、DataFrameのインデックスを変換することができたのですが、  
もっとスマートな方法ありますでしょうか？  
（実際は、データの件数が増えることを前提としています。）  
よろしくお願いします。

[code]

    import pandas as pd
    import matplotlib
    import matplotlib.pyplot as plt
    # インデックスを変換する関数
    def convert_index(df:pd.DataFrame, target_index:pd.DatetimeIndex=None)-> pd.DataFrame:
        if target_index is None:
            target_index = pd.date_range(start=df.index[0].floor('D'), end=df.index[-1].ceil('D'), freq='D')
            print(target_index)
        s = pd.Series(index=target_index, dtype=object, name='dummy')
        df = pd.concat([df, s], axis='columns') # インデックスを合成
        df = df.drop(columns=[s.name])
        df = df.interpolate(method='time', limit_direction='both') # 線形補間
        df = df.join(s, how='right') # target_indexを含む行を抽出
        df = df.drop(columns=[s.name])
        return df
    
    # テスト用データ用意
    df_in = pd.DataFrame(data={ 'value':[100, 200, 160] }, index=[
        pd.Timestamp('2021/12/01 01:00'),
        pd.Timestamp('2021/12/01 23:00'),
        pd.Timestamp('2021/12/03 16:00'),
    ])
    df_out = convert_index(df_in)
    
    display(df_in)
    display(df_out)
    # グラフ表示（結果確認用）
    plt.scatter(x=df_in.index.to_list(), y=df_in['value']) # 点で表示
    plt.plot(df_out) # 線で表示
    plt.show()
    
[/code]


CC BY-SA 4.0
2021-12-02T07:12:56.147
83913
2021-12-04T08:27:11.910
48481
question
python pandas
時系列の値を線形補間し、別の時系列インデックスに変換する方法


`date_range` の頻度？を細かくして補間し, そこから求める頻度でリサンプリングする方法

[code]

    def convert_index(df:pd.DataFrame, target_index:pd.DatetimeIndex=None)-> pd.DataFrame:
        if target_index is None:
            target_index = pd.date_range(start=df.index.min().floor('D'),
                                         end=df.index.max().ceil('D'),
                                         freq='1h')
    
        return (df.reindex(target_index)
                  .interpolate(method='time', limit_direction='both')
                  .asfreq('1D'))
    
[/code]


CC BY-SA 4.0
2021-12-02T23:03:20.757
83924
2021-12-02T23:03:20.757
43025
83913
answer


ありがとうございます。  
インデックスのTimestampにミリ秒以下の値が含まれていると、線形補間の対象外となることが分かりました。  
上段に期待結果、下段にreindexを利用したときの結果を添付いたします。  
reindex便利そうですね。  
値なしのSeriesオブジェクトを作成しconcatしたところがスマートではないですね。  
使いこなせるようもう少し調べてみます。

[![期待する結果](https://i.stack.imgur.com/QHhmx.png)](https://i.stack.imgur.com/QHhmx.png)

[![reindexを利用したときの結果](https://i.stack.imgur.com/lmIlk.png)](https://i.stack.imgur.com/lmIlk.png)

ファイル添付できないようなので、参考情報として、以下にin_data.csvの一部を記載いたします。

[code]

    ,value
    2021-02-03 00:00:00+09:00,10000
    2021-02-11 04:32:25.945945946+09:00,10330
    2021-02-19 09:04:51.891891892+09:00,10660
    2021-02-27 13:37:17.837837838+09:00,11000
    2021-03-07 18:09:43.783783784+09:00,11330
    2021-03-15 22:42:09.729729730+09:00,11660
    2021-03-24 03:14:35.675675676+09:00,12000
    2021-04-01 07:47:01.621621622+09:00,12330
    2021-04-09 12:19:27.567567568+09:00,12660
    
[/code]


CC BY-SA 4.0
2021-12-03T02:30:31.960
83930
2021-12-03T02:55:22.217
2021-12-03T02:55:22.217
3060
48481
83913
answer


ありがとうございます。  
「ate_range の頻度？を細かくして補間し, そこから求める頻度でリサンプリングする方法」  
多分理解できました。解決できたと思います。  
1.アップサンプルは、reindex+interpolate（もしくはresample）を利用する。  
interpolateで指定した単位より、細かい日時のレコードは線形補間の対象外となるので注意。  
2.ダウンサンプルは、asfreqを利用する。  
asfreqはあくまで抽出なので、少なくとも等間隔のレコードが含まれている必要がある。  
3.時系列のインデックスは、等間隔なインデックスに統一したほうが処理しやすい  
ある不揃いな（等間隔ではない）データの、インデックスに合わせるより、日ごと、時間ごとなどの等間隔なインデックスに変換（統一）したほうが処理しやすい。

[code]

    def convert_index(df:pd.DataFrame)-> pd.DataFrame:
        target_index = pd.date_range(start=df.index.min().floor('D'),
                                        end=df.index.max().ceil('D'),
                                        freq='1h')
        df.index = df.index.floor('1h') # ←インデックスを1h単位で丸めて統一。こうしないと後のreindexで削除されてしまう。すべてのインデックスが上記pd.date_rangeに含まれているなら実行不要。
        df = df.groupby(level=0).mean() # ←丸め後（1h以内に）に、インデックスが重複しないなら、この行の実行は不要
    
        return (df.reindex(target_index)
                  .interpolate(method='time', limit_direction='both')
                  .asfreq('1D'))
    
[/code]

以下のURLも参考になりました。  
<<https://ari23.hatenablog.com/entry/pandas-resample-asfreq>>


CC BY-SA 4.0
2021-12-03T15:16:28.630
83945
2021-12-04T08:27:11.910
2021-12-04T08:27:11.910
35267
35267
83913
answer