非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

【Python】Pandasでcsvデータを読み込んだら時間計算でハマったので対処法を書く

   

データ分析でCSVファイルを読み込むとき、PythonのPandasは非常に便利なライブラリですが日時データの計算で予期せぬエラーや思わぬ挙動に悩まされることも少なくありません。実際に時間計算でハマったので備忘録のために書き留めておきます。

対象のCSVファイルと最初のプログラム

まず用意したのがこちらのCSVファイル。日足のドル円データです。左列に日時が入っています。

 

こちらが最初のソースコード。CSVを呼び出したあとに時間計算しているのがわかると思います。

import pandas as pd

df = pd.read_csv('usd_jpy_data.csv')
df = df[['Date', 'Open', 'High', 'Low', 'Close']]

df['weeks'] = (df['Date'] - df['Date'][0])
print(df)
 

 

TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’

このエラー TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’ は、「文字列同士の引き算はできない」という意味です。Pythonでは文字列(str型)に対して直接数値演算を行うことができないため、このエラーが出ます。

解決法

#New!の行が示すように、pandasto_datetime関数で文字列から日時型に変換すればOKです。まあ、ここはハマったというほどのものではありません。

import pandas as pd

df = pd.read_csv('usd_jpy_data.csv')
df = df[['Date', 'Open', 'High', 'Low', 'Close']]
df['Date'] = pd.to_datetime(df['Date']) #New!

df['weeks'] = (df['Date'] - df['Date'][0])
print(df)
 

 

 

インデックス列が日付でない

上記プログラムを実行するとエラーは出なくなります。しかし、以下のように左端に連番のインデックス行が現れてしまいます。

                         Date        Open        High         Low       Close    weeks
0   2023-11-06 00:00:00+00:00  149.449005  149.830002  149.382004  149.449005   0 days
1   2023-11-07 00:00:00+00:00  149.988998  150.686996  149.968994  149.988998   1 days
2   2023-11-08 00:00:00+00:00  150.395996  150.981995  150.345993  150.395996   2 days
3   2023-11-09 00:00:00+00:00  150.863998  151.175995  150.798004  150.863998   3 days
4   2023-11-10 00:00:00+00:00  151.348999  151.559006  151.225006  151.348999   4 days
 

 

そこで、時間列(Date列)をインデックス列として認識させましょう。#New!の行を追加します。

import pandas as pd

df = pd.read_csv('usd_jpy_data.csv')
df = df[['Date', 'Open', 'High', 'Low', 'Close']]
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace = True) #New

df['weeks'] = (df['Date'] - df['Date'][0])
print(df)
 

 

 

KeyError: ‘Date’

で、最後にこのエラーが出ました。Date列をインデックス列として設定してしまったため、df[‘Date’]で値を取り出せなくなったわけです。

これについてはかなり悩みましたが、苦肉の策でデータ列をコピーすることにしました。#New!の行のところです。

import pandas as pd

df = pd.read_csv('usd_jpy_data.csv')
df = df[['Date', 'Open', 'High', 'Low', 'Close']]
df['Date'] = pd.to_datetime(df['Date'])
df['Date2'] = df['Date'] #New
df.set_index('Date', inplace = True)

df['weeks'] = (df['Date2'] - df['Date2'][0])
print(df)
 

 

この結果、エラーは発生せず以下のような出力をするようになりました。Date2が余計ですが日付計算をさせる以上は致し方なしかなと。

                                 Open        High         Low       Close                     Date2    weeks
Date                                                                                                        
2023-11-06 00:00:00+00:00  149.449005  149.830002  149.382004  149.449005 2023-11-06 00:00:00+00:00   0 days
2023-11-07 00:00:00+00:00  149.988998  150.686996  149.968994  149.988998 2023-11-07 00:00:00+00:00   1 days
2023-11-08 00:00:00+00:00  150.395996  150.981995  150.345993  150.395996 2023-11-08 00:00:00+00:00   2 days
2023-11-09 00:00:00+00:00  150.863998  151.175995  150.798004  150.863998 2023-11-09 00:00:00+00:00   3 days
2023-11-10 00:00:00+00:00  151.348999  151.559006  151.225006  151.348999 2023-11-10 00:00:00+00:00   4 days
 

 

 

スポンサーリンク

 - Python