【Pandas】カラムのマルチインデックスを解除する【Python】
MAX
MAX999blog
Pythonで月単位の日付計算をする場合、relativedeltaを使用すると便利だが、DataFrameやSeriesで使おうとするとエラーとなる。
そのため、lambda式で1行ずつ適用してやる必要がある。
また、月末の日付について、1か月後、2か月後なども求めたい場合、注意する必要がある。
1import pandas as pd
2from dateutil.relativedelta import relativedelta
3
4# DataFrame作成
5date1 = ["2020-1-1", "2020-1-5", "2020-2-3"]
6df_date = pd.DataFrame(data={"date1": date1})
7df_date["date1"] = pd.to_datetime(df_date["date1"], format="%Y-%m-%d")
8
9# 2か月後の日付計算
10df_date["date2"] = df_date["date1"].apply(lambda x: x + relativedelta(months=2))
11print(df_date)
12# date1 date2
13# 0 2020-01-01 2020-03-01
14# 1 2020-01-05 2020-03-05
15# 2 2020-02-03 2020-04-03
計算速度的には、なるべくapplyは使いたくないが、月単位の計算をしたい場合は、使うしかない。
relativedeltaの引数monthsに負の値を指定すれば、「Xか月前」も計算可能。
また、x – relativedelta(months=1)とすることで1か月前を計算することも可能。
Xか月後を計算した値に対してXか月前を計算しても元に戻らない場合がある。
1date = ["2020-1-29", "2020-1-30", "2020-1-31", "2020-5-31"]
2
3df_date = pd.DataFrame(data={"date1": date})
4df_date["date1"] = pd.to_datetime(df_date["date1"], format="%Y-%m-%d")
5
6# 1か月後の日付を計算
7df_date["date2"] = df_date["date1"].apply(lambda x: x + relativedelta(months=1))
8# 計算した1か月後の日付について、の1か月前の日付を計算
9df_date["date3"] = df_date["date2"].apply(lambda x: x + relativedelta(months=-1))
10print(df_date)
11# date1 date2 date3
12# 0 2020-01-29 2020-02-29 2020-01-29
13# 1 2020-01-30 2020-02-29 2020-01-29
14# 2 2020-01-31 2020-02-29 2020-01-29
15# 3 2020-05-31 2020-06-30 2020-05-30
1月30日、31日の1か月後は2月29日となる(2020年は閏年)。
5月31日の1か月後は6月30日となる。
これらの計算した1か月後の日付に対して、1か月前の日付に戻そうとすると、1月30日や1月31日は1月29日になり、5月31日は5月30日になる。
毎月28日以前であれば、この問題が発生することはないため、Xか月後を計算したりするのはそこまで問題にはならない。
月末の日付に対してXか月後を計算する必要がある場合、こういう事象が発生することを念頭に置いて計算するか、30日後などの日付を計算した方が良い。
なお、求めたい日付が1か月後の場合、1か月の日数を加算することでも1か月後の日付を求めることができる。
上記の方法でも月末問題は発生するので注意が必要。
2か月後や3か月後など、数か月後の日付を求めたい場合、上記の方法は使いにくいため、relativedeltaをlanbda式で1行ずつ適用することとなる。