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
