pandasで年末と年初の行を抽出
indexがdatetime型のDataFrameを作成
indexがdatetime型のDataFrameを作成する必要があります。
例えば、下記のようにcsvデータを読み込んで、indexがdatetime型にします。
参考:pandas.read_csv()のindex_colの指定とparse_dates=Trueで、インデックスの列をdatetime型に変換
data = pd.read_csv('in.txt', names=('Date', 'Value'), index_col='Date', parse_dates=True)
DataFrame.resample()で行を抽出
続いて、DataFrame.resample()で行を抽出します。
年単位で行を抽出する場合にはresample()の引数に、'A' もしくは 'AS' を指定します。
'AS' indexは年初の日付
'A' indexは年末の日付
更に、その年の最初の日付の行を抽出するにはfirst()を、その年の最後の行を抽出するにはlast()を使います。
DataFrame.resample().first() その年の最初の日付の行を抽出
DataFrame.resample().last() その年の最後の日付の行を抽出
年単位でその年の最初(年初)の行を抽出して出力
#indexは年初の日付:年単位でその年の最初の行を抽出して出力 DataFrame.resample('AS').first() #indexは年末の日付:年単位でその年の最初の行を抽出して出力 DataFrame.resample('A').first()
年単位でその年の最後(年末)の行を抽出して出力
#indexは年初の日付:年単位でその年の最後の行を抽出して出力 DataFrame.resample('AS').last() #indexは年末の日付:年単位でその年の最後の行を抽出して出力 DataFrame.resample('A').last()
サンプルコード
下記がサンプルコードになります。
in.txtが下記のようにあったとします。
$ cat in.txt 20160105,0 20160402,1 20161231,2 20170101,3 20170406,4 20171221,5 20180102,6 20180406,7 20181230,8
下記がサンプルコードになります。
$ cat sample.py #!/usr/bin/env python3 # coding: UTF-8 import pandas as pd data = pd.read_csv('in.txt', names=('Date', 'Value'), index_col='Date', parse_dates=True) print("dataの中身を出力") print (data) print("indexは年初の日付:年単位でその年の最初の行を抽出して出力") print(data.resample('AS').first()) print("indexは年初の日付:年単位でその年の最後の行を抽出して出力") print(data.resample('AS').last()) print("indexは年末の日付:年単位でその年の最初の行を抽出して出力") print(data.resample('A').first()) print("indexは年末の日付:年単位でその年の最後の行を抽出して出力") print(data.resample('A').last())
下記が実行結果になります。
$ ./sample.py dataの中身を出力 Value Date 2016-01-05 0 2016-04-02 1 2016-12-31 2 2017-01-01 3 2017-04-06 4 2017-12-21 5 2018-01-02 6 2018-04-06 7 2018-12-30 8 indexは年初の日付:年単位でその年の最初の行を抽出して出力 Value Date 2016-01-01 0 2017-01-01 3 2018-01-01 6 indexは年初の日付:年単位でその年の最後の行を抽出して出力 Value Date 2016-01-01 2 2017-01-01 5 2018-01-01 8 indexは年末の日付:年単位でその年の最初の行を抽出して出力 Value Date 2016-12-31 0 2017-12-31 3 2018-12-31 6 indexは年末の日付:年単位でその年の最後の行を抽出して出力 Value Date 2016-12-31 2 2017-12-31 5 2018-12-31 8