4
3

 先ほどpythonで開発をしている最中にDataFrameの時系列データの時間列をエポック秒に変換する際に、非常に苦労したので僕の試行錯誤の結果が似たような状況のどなたかの役に立てばと思い備忘録として書いていきたいと思います。

過程

 現在FX関連のとあるツールを自作しているのですが、APIから取得したレートの情報の時系列DataFrameについて時間に関しても整数値で扱えた方が何かと都合がいいと思い、Datetimeをエポック秒に変換し始めました。
 最初はindexの情報が書き換えられないことを知らず、

#tickは一定期間のOHLCの価格などが入っているDataFrame形式の多次元リスト
tick["Datetime"] = pd.to_datetime(tick["Datetime"]).apply(lambda x: x.timestamp())

 この方法で直接indexを置き換えてやろうと思ったのですが、結果は失敗で以下のエラーが出てきました。

KeyError: 'Datetime'

 次に、indexの内容は書き換えられないことと、set_index()とreset_index()でindexを設定・解除できることを知り

#indexを削除
tick.reset_index(inplace=True)
#Datetimeをエポック秒に変換
tick["Datetime"] = pd.to_datetime(tick["Datetime"]).apply(lambda x: x.timestamp())
#Datetimeをindexに設定
tick.set_index("Datetime")

print(tick)

これを試してみた結果、

        Datetime        Open        High         Low       Close   Adj Close  Volume
0   1.721343e+09  157.287994  157.304993  157.285004  157.300003  157.300003       0
1   1.721343e+09  157.298004  157.306000  157.287994  157.289001  157.289001       0
2   1.721343e+09  157.292007  157.300995  157.281998  157.281998  157.281998       0
3   1.721343e+09  157.285004  157.287994  157.261002  157.261993  157.261993       0
(中略)
56  1.721346e+09  157.130005  157.132996  157.117996  157.132004  157.132004       0
57  1.721347e+09  157.128998  157.139999  157.110001  157.112000  157.112000       0
58  1.721347e+09  157.123993  157.123993  157.123993  157.123993  157.123993       0

無事エポック秒に変換はできたものの、謎のIDが勝手にindexとして追加されてしまいました。正直今の段階ではこのままでも問題はなかったのですが、今後このデータは大量に蓄積していく予定だったのでできる限り余計な情報は省きたいと思いなんとかしてこの列を消して変換後のDatetimeをindexに戻せないかと思い、力業で削除してみました。

#indexを削除
tick.reset_index(inplace=True)
#Datetimeをエポック秒に変換
tick["Datetime"] = pd.to_datetime(tick["Datetime"]).apply(lambda x: x.timestamp())
#ID列を削除
tick.drop(tick.columns[-1], axis=1, inplace=True)
#Datetimeをindexに設定
tick.set_index("Datetime")

print(tick)

結果はなにも変わりませんでした。

        Datetime        Open        High         Low       Close   Adj Close  Volume
0   1.721343e+09  157.287994  157.304993  157.285004  157.300003  157.300003       0
1   1.721343e+09  157.298004  157.306000  157.287994  157.289001  157.289001       0
2   1.721343e+09  157.292007  157.300995  157.281998  157.281998  157.281998       0
3   1.721343e+09  157.285004  157.287994  157.261002  157.261993  157.261993       0
(中略)
56  1.721346e+09  157.130005  157.132996  157.117996  157.132004  157.132004       0
57  1.721347e+09  157.128998  157.139999  157.110001  157.112000  157.112000       0
58  1.721347e+09  157.123993  157.123993  157.123993  157.123993  157.123993       0

この後色々調べていった結果、set_indexのパラメータをinplace = Trueにすれば既存のindexを削除して新たにindexを指定できると知り、以下の方法を試した結果

#indexを削除
tick.reset_index(inplace=True)
#Datetimeをエポック秒に変換
tick["Datetime"] = pd.to_datetime(tick["Datetime"]).apply(lambda x: x.timestamp())
#ID列を削除
tick.drop(tick.columns[-1], axis=1, inplace=True)
#Datetimeをindexに設定
tick.set_index("Datetime",inplace = True)

print(tick)
                    Open        High         Low       Close   Adj Close  Volume
Datetime
1.721344e+09  157.264008  157.270996  157.261002  157.264008  157.264008       0
1.721344e+09  157.264008  157.270004  157.259995  157.263000  157.263000       0
1.721344e+09  157.263000  157.270996  157.259995  157.261993  157.261993       0
(中略)
1.721347e+09  157.097000  157.126999  157.085007  157.087997  157.087997       0
1.721348e+09  157.087997  157.139999  157.084000  157.119003  157.119003       0
1.721348e+09  157.104996  157.104996  157.104996  157.104996  157.104996       0

無事成功しました。

パラメータ"inplace"について

inlaceは和訳すると「決まった場所に~」という意味で、pandasにおいては元のデータを変更するかどうかを指定する際に使われるようです。一度データを削除してしまうと変更が不可逆になってしまうためデフォルトではFalseになっているようですので、今回は問題ありませんでしたが不用意に指定しない方がよさそうです。

最後に

 今回の話題は多くの人にとっては取るに足らない話題かもしれませんが、僕と似たような独学で知識に抜けがある人などの参考になれば幸いです。もしこの文章を読まれた方で理解が間違っている点や改善点などに気づいた方は是非指摘していただけると嬉しいです。拙い文章でしたが最後まで読んでくださりありがとうございました。

追記

少し認識の違いがあったかもしれないので一応書き残しておきます。

①「indexの情報が書き換えられない」
indexの情報が書き換えられないのではなく、エラー内容がKey ErrorなのでDataFrameのKeyとしてindexを指定できないということかもしれないです。結果として書き換えができなかった事実は変わらないのですが認識が間違ってたかもしれないので訂正しておきます。

②最後のコードの

tick.drop(tick.columns[-1], axis=1, inplace=True)

の部分
この方法で指定の列が削除できるのは間違いないのですが、この次の

tick.set_index("Datetime",inplace = True)

の部分でinplace = Trueを指定して既存のindexを削除して新たなIndexを指定しているので不要な一文だったかもしれないです。

4
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3