Pandas Dataframe-20年の履歴データから1日の特定の時間を削除


8

20年前の1つの証券の株式市場データがあります。データは現在、次の形式でPandas DataFrameにあります。

ここに画像の説明を入力してください

問題は、DataFrameに「営業時間外」の取引データが必要ないことです。問題の市場は午前9時30分から午後4時までです(各取引日の09時30分から16時)。この時間枠内にないデータのすべての行を削除したいと思います。

私の本能はPandasマスクを使用することです。これは、1日で特定の時間を必要とする場合の方法を知っています。

mask = (df['date'] > '2015-07-06 09:30:0') & (df['date'] <= '2015-07-06 16:00:0')
sub = df.loc[mask]

ただし、20年の期間の1日の特定の時間のデータを削除するために回転ベースでどのように使用するかはわかりません。


columnのデータ型は何ですかdate。このコマンドを実行print(df['date'].map(type)) して、その出力を質問に投稿できますか?
アンディL.

回答:


8

ここでの問題は、データのインポート方法です。04:00が午前か午後かを示す指標はありませんか?しかし、あなたのコメントに基づいて、私たちはそれがPMであると仮定する必要があります。ただし、入力ではAMと表示されています。

これを解決するには、OR句を使用して2つの条件を含める必要があります。

  1. 9:30-11:59
  2. 0:00〜4:00

入力:

df = pd.DataFrame({'date':   {880551: '2015-07-06 04:00:00', 880552: '2015-07-06 04:02:00',880553: '2015-07-06 04:03:00', 880554: '2015-07-06 04:04:00', 880555: '2015-07-06 04:05:00'},
                   'open':   {880551: 125.00, 880552: 125.36,880553: 125.34, 880554: 125.08, 880555: 125.12},
                   'high':   {880551: 125.00, 880552: 125.36,880553: 125.34, 880554: 125.11, 880555: 125.12},
                   'low':    {880551: 125.00, 880552: 125.32,880553: 125.21, 880554: 125.05, 880555: 125.12},
                   'close':  {880551: 125.00, 880552: 125.32,880553: 125.21, 880554: 125.05, 880555: 125.12},
                   'volume': {880551: 141, 880552: 200,880553: 750, 880554: 17451, 880555: 1000},
                   },
                   )


df.head()

    date    open    high    low close   volume
880551  2015-07-06 04:00:00 125.00  125.00  125.00  125.00  141
880552  2015-07-06 04:02:00 125.36  125.36  125.32  125.32  200
880553  2015-07-06 04:03:00 125.34  125.34  125.21  125.21  750
880554  2015-07-06 04:04:00 125.08  125.11  125.05  125.05  17451
880555  2015-07-06 04:05:00 125.12  125.12  125.12  125.12  1000

from datetime import time

start_first = time(9, 30)
end_first = time(11, 59)
start_second = time(0, 00)
end_second = time(4,00)
df['date'] = pd.to_datetime(df['date'])
df= df[(df['date'].dt.time.between(start_first, end_first)) | (df['date'].dt.time.between(start_second, end_second))]
df
date    open    high    low close   volume
880551  2015-07-06 04:00:00 125.0   125.0   125.0   125.0   141

上記は良い習慣ではありません。このようなあいまいなデータを使用しないことを強くお勧めします。長い時間の解決策は、午前/午後でデータを正しく入力することです。

正しいデータ形式の場合、2つの方法でそれを実現できます。

1)日時を使用する

from datetime import time

start = time(9, 30)
end = time(16)
df['date'] = pd.to_datetime(df['date'])
df= df[df['date'].dt.time.between(start, end)]

2)日時インデックスでのみ機能する時間間隔を使用する

df['date'] = pd.to_datetime(df['date'])

df = (df.set_index('date')
          .between_time('09:30', '16:00')
          .reset_index())

それでもエラーが発生する場合は、行ごとのアプローチと正確なエラーで質問を編集してください。


その結果、次のエラーが発生しますTypeError: Index must be DatetimeIndex
HMLDude

私の回答を編集、df ['date'] = pd.to_datetime(df ['date'])
Bhavesh Ghodasara

このSO投稿から、between_timeデータフレームが日時インデックスである必要があるように見えます。OPはDataFrameレベルで試すことができます:day_df = df.set_index('date').between_time('9:30', '16:00')
パフェ

BhaveshGhodasara私はあなたがあなたの最新の編集で提案したものを試しました、そして結果は同じTypeError: Index must be DatetimeIndexです。
HMLDude

@Parfait私もあなたの提案を試しました、そしてもう一度エラーメッセージは:TypeError: Index must be DatetimeIndexでした。
HMLDude

3

答えはすでにコメント(@Parfait.between_time)に含まれていると思いますが、問題のデバッグで失われました。あなたの見えるdf['date']列がタイプではありませんDatetime、まだ。

これはそれを修正して必要な結果を得るのに十分なはずです:

df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
df = df.between_time('9:30', '16:00')

0

このコード例は、Bhavesh Ghodasara、Parfait、およびjorijnsmitから提供された回答を、コメント付きの1つの完全な例にまとめたものです。

import pandas as pd

# example dataframe containing 6 records: 2 days of 3 records each in which all cases are covered:
# each day has one record before trading hours, one record during trading hours and one recrod after trading hours
df = pd.DataFrame({'date':   {0: '2015-07-06 08:00:00', 1: '2015-07-06 13:00:00', 2: '2015-07-06 18:00:00', 
                              3: '2015-07-07 08:00:00', 4: '2015-07-07 13:00:00', 5: '2015-07-07 18:00:00'},
                   'open':   {0: 125.00, 1: 125.36, 2: 125.34, 3: 125.08, 4: 125.12, 5: 125.37},
                   'high':   {0: 125.00, 1: 125.36, 2: 125.34, 3: 125.08, 4: 125.12, 5: 125.37},
                   'low':    {0: 125.00, 1: 125.36, 2: 125.34, 3: 125.08, 4: 125.12, 5: 125.37},
                   'close':  {0: 125.00, 1: 125.36, 2: 125.34, 3: 125.08, 4: 125.12, 5: 125.37},
                   'volume': {0: 141, 1: 200, 2: 750, 3: 17451, 4: 1000, 5: 38234},
                   },
                   )

# inspect the example data set
df.head(6)

# first, ensure that the 'date' column is of the correct data type: MAKE IT SO!
df['date'] = pd.to_datetime(df['date'])

# inspect the data types: date column should be of type 'datetime64[ns]'
print(df.dtypes)

# set the index of the dataframe to the datetime-type column 'data'
df = df.set_index('date')

# inspect the index: it should be a DatetimeIndex of dtype 'datetime64[ns]'
print(df.index)

# filter the data set
df_filtered = df.between_time('9:30', '16:00')

# inspect the filtered data set: Voilà! No more outside trading hours records.
df_filtered.head()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.