python pandas datetimeIndexまたはdatetimeタイプ列を使用したデータを時間(h:m:s)条件でフィルタする方法

52381 ワード

不思議なpandas、使えば使うほど面白いと思います.pandasのスライス機能は非常に強力で、datetimeタイプ列を含むdataframeとdatetimeIndexを使用するSeriesに対して、所定のdatetime形式の文字列('2019-07-26 08:00:00', '2019-07', '2019-07-26', '2019-07-26 08:00')によって日付時間のフィルタリングが可能である.
BUT!
ある周期(年、月、週)内の特定の時間(h:m:s)のデータを検索したい場合(例えば、1年間の毎日の08:00のデータ行を表示する)、上のスライスフィルタは適用されません!文字列によって時間が判定されますが、クエリされた列はdatetimeタイプのデータで、date(年月日)が含まれているため、自動的にdateを削除するまでスマートではなく、timeでフィルタリングするだけで、返される結果は望ましくないに違いありません.
では、このニーズについては、2つの状況に分けて解決することができる:(本明細書では、0.24.2バージョンpandasに基づいて検証が通過した)
一、フィルタリングするデータは、datetimeIndexをindexとして使用します.
indexにはdatetimeIndexの2つの方法があります.1つはindex.indexer_at_time()で、指定された時間のデータを抽出する行番号です.
  datetimeIndex  Series      (h:m:s)     
locs = test.index.indexer_at_time('7:00:00')
print(locs)

           
>>> [ 28 124]
print(type(locs))
>>> <class 'numpy.ndarray'>

  iloc  ,             
print(test.iloc[locs])
>>> 
                        VALUE
START_TIME                   
2019-07-22 07:00:00  24238.11
2019-07-23 07:00:00  21946.81

  
print(type(test.iloc[locs]))
  >>> <class 'pandas.core.frame.DataFrame'>

もう1つはindex.indexer_between_time()であり、これは所定の期間でフィルタリングされ、条件に合致する行番号を返すことができる.具体的なパラメータは、indexer_between_time(start_time, end_time, include_start=True,include_end=True),開始時間(string),停止時間(string),開始時間(True/False),終了時間(True/False)を含む.ここに含まれる起止時間は,クエリ時の「左閉か右閉か」に従って理解できる.
  datetimeIndex  Series       ()
start_time = '08:00:00'
end_time = '09:00:00'
locs2 = test.index.indexer_between_time(start_time, end_time, include_start=True,include_end=False)

              
print(locs2)
>>> [ 32  33  34  35 128 129 130 131]
print(type(locs2))
>>> <class 'numpy.ndarray'>

  
print(test.iloc[locs2])
>>> 
                        VALUE
START_TIME                   
2019-07-22 08:00:00  31107.17
2019-07-22 08:15:00  27614.50
2019-07-22 08:30:00  30453.01
2019-07-22 08:45:00  30660.73
2019-07-23 08:00:00  28185.59
2019-07-23 08:15:00  28690.62
2019-07-23 08:30:00  29500.40
2019-07-23 08:45:00  30008.18

二、フィルタリングするデータは、indexとしてdatetimeIndexを使用しないが、このDataFrameには、datetimeタイプのデータが使用されている少なくとも1つの列がある.
 datetimeIndex    DataFrame,   datetime     ,
   datetime.time       datetime column           。
          “  :  : ”    。
pandas datetime  column  dt  ,  datetime         .time == .time    。
(   dt    datetime,datetime       .year, .month, .day, .time, .hour ,     )

 datetime.datetime.time      datetime.time     
       time:datetime.datetime.strptime('time string', 'format string')
import datetime
print(datetime.datetime.strptime('08:00','%H:%M').time())
>>> 08:00:00
print(type(datetime.datetime.strptime('08:00','%H:%M').time()))
>>> datetime.time

 :df ,df['START_TIME']     datetime    ,  df.START_TIME      

 df.query  (    ,    )    time     
print(df.query('START_TIME.dt.time == datetime.datetime.strptime("08:00","%H:%M").time()'))

 df        time     
print(df[df.START_TIME.dt.time == datetime.datetime.strptime("08:00","%H:%M").time()])

            。
             START_TIME            END_TIME         NE_NAME     VALUE
32  2019-07-22 08:00:00 2019-07-22 08:15:00            baka  31107.17
128 2019-07-23 08:00:00 2019-07-23 08:15:00            baka  28185.59


         ,    start_time end_time,
start_time = datetime.datetime.strptime('16:00','%H:%M').time()
end_time = datetime.datetime.strptime('16:30','%H:%M').time()
ne_list = ['baka']
   df['START_TIME']  :    start_time、    end_time,  df['NE_NAME'] ne_list        
print(df[(df.START_TIME.dt.time >= start_time) & (df.START_TIME.dt.time <= end_time) & (df.NE_NAME.isin(ne_list))])
>>> 
             START_TIME            END_TIME         NE_NAME     VALUE
64  2019-07-22 16:00:00 2019-07-22 16:15:00            baka  28861.52
65  2019-07-22 16:15:00 2019-07-22 16:30:00            baka  28934.74
66  2019-07-22 16:30:00 2019-07-22 16:45:00            baka  29235.14
160 2019-07-23 16:00:00 2019-07-23 16:15:00            baka  26666.94
161 2019-07-23 16:15:00 2019-07-23 16:30:00            baka  28675.96
162 2019-07-23 16:30:00 2019-07-23 16:45:00            baka  28586.23


       time_list,  .isin      ,                   。
      ,     9 15   1 15       。
                   ,                       。
(  ,               、     ,       ,    ,        ,  |      。)
time_list = []
time_list.append(datetime.datetime.strptime("08:00","%H:%M").time())
time_list.append(datetime.datetime.strptime("09:15","%H:%M").time())
time_list.append(datetime.datetime.strptime("11:30","%H:%M").time())
time_list.append(datetime.datetime.strptime("13:45","%H:%M").time())
ne_list = ['baka']
print(df[(df.START_TIME.dt.time.isin(time_list)) & (df.NE_NAME.isin(ne_list))])
>>> 
             START_TIME            END_TIME         NE_NAME     VALUE
32  2019-07-22 08:00:00 2019-07-22 08:15:00            baka  31107.17
37  2019-07-22 09:15:00 2019-07-22 09:30:00            baka  31268.25
46  2019-07-22 11:30:00 2019-07-22 11:45:00            baka  29116.12
55  2019-07-22 13:45:00 2019-07-22 14:00:00            baka  24565.35
128 2019-07-23 08:00:00 2019-07-23 08:15:00            baka  28185.59
133 2019-07-23 09:15:00 2019-07-23 09:30:00            baka  30427.79
142 2019-07-23 11:30:00 2019-07-23 11:45:00            baka  28852.88
151 2019-07-23 13:45:00 2019-07-23 14:00:00            baka  24931.63

     
start_time = datetime.datetime.strptime('16:00','%H:%M').time()
end_time = datetime.datetime.strptime('16:30','%H:%M').time()
start_time1 = datetime.datetime.strptime('18:00','%H:%M').time()
end_time1 = datetime.datetime.strptime('18:30','%H:%M').time()
ne_list = ['baka']

         
print(df[ (((df.START_TIME.dt.time >= start_time) & (df.START_TIME.dt.time <= end_time)) | 
((df.START_TIME.dt.time >= start_time1) & (df.START_TIME.dt.time <= end_time1))) & 
(df.NE_NAME.isin(ne_list))]
)
>>> 
             START_TIME            END_TIME         NE_NAME     VALUE
64  2019-07-22 16:00:00 2019-07-22 16:15:00            baka  28861.52
65  2019-07-22 16:15:00 2019-07-22 16:30:00            baka  28934.74
66  2019-07-22 16:30:00 2019-07-22 16:45:00            baka  29235.14
72  2019-07-22 18:00:00 2019-07-22 18:15:00            baka  28193.47
73  2019-07-22 18:15:00 2019-07-22 18:30:00            baka  27489.57
74  2019-07-22 18:30:00 2019-07-22 18:45:00            baka  27459.55
160 2019-07-23 16:00:00 2019-07-23 16:15:00            baka  26666.94
161 2019-07-23 16:15:00 2019-07-23 16:30:00            baka  28675.96
162 2019-07-23 16:30:00 2019-07-23 16:45:00            baka  28586.23
168 2019-07-23 18:00:00 2019-07-23 18:15:00            baka  26940.09
169 2019-07-23 18:15:00 2019-07-23 18:30:00            baka  26536.41
170 2019-07-23 18:30:00 2019-07-23 18:45:00            baka  25966.47

标题外:datetimeタイプの列を、timeだけのSeriesを作って出てくるようにすると、それができます.
ts = df.START_TIME.dt.time
print(type(ts))
>>> <class 'pandas.core.series.Series'>
print(ts)
>>> 
0       00:00:00
1       00:15:00
2       00:30:00
          ...   
1533    23:15:00
1534    23:30:00
1535    23:45:00
Name: START_TIME, Length: 1536, dtype: object


以上です.