簡體   English   中英

如何以較低的頻率重新采樣 Pandas DataFrame 並阻止它產生 NaN?

[英]How to resample a Pandas DataFrame at a lower frequency and stop it creating NaN's?

我有一個帶有日期時間索引的 Pandas Dataframe。 它具有以 1 分鍾間隔采樣的一些股票的收盤價。 我想重新采樣這個 dataframe 並以 5 分鍾的間隔獲取它,就好像它是以這種方式收集的一樣。 例如:

                         SPY     AAPL
DateTime        
2014-01-02 09:30:00     183.91  555.890
2014-01-02 09:31:00     183.89  556.060
2014-01-02 09:32:00     183.90  556.180
2014-01-02 09:33:00     184.00  556.550
2014-01-02 09:34:00     183.98  556.325
2014-01-02 09:35:00     183.89  554.620
2014-01-02 09:36:00     183.83  554.210

我需要得到類似的東西

                         SPY     AAPL
DateTime        
2014-01-02 09:30:00     183.91  555.890
2014-01-02 09:35:00     183.89  554.620

自然的方法是使用 Pandas 的resample()asfreq() 他們確實生產了我需要的東西,但是也有一些不受歡迎的 output 。 我的樣本從給定工作日的下午 4 點到次日上午 9:30 沒有觀察到,因為在這些時間段內交易暫停。 這些提到的方法最終會在實際上沒有數據可重采樣的這些時期內用 NaN 完成 dataframe。 我可以使用任何選項來避免這種行為嗎? 從下午 4:05 到第二天早上 9:25,我得到了很多 NaN,僅此而已!

我快速而骯臟的解決方案如下:

Prices_5min = Prices[np.remainder(Prices.index.minute, 5) == 0]

盡管我相信這是一個快速而優雅的解決方案,但我會假設resample()有一些選項來執行此任務。 有任何想法嗎? 非常感謝!


編輯:在關於不受歡迎的 output 的評論之后,我添加了以下代碼來展示問題:

New_Prices = Prices.asfreq('5min')
New_Prices.loc['2014-01-02 15:50:00':'2014-01-03 9:05:00']
Out:
                         SPY    AAPL
DateTime        
2014-01-02 15:50:00     183.12  552.83
2014-01-02 15:55:00     183.08  552.89
2014-01-02 16:00:00     182.92  553.18
2014-01-02 16:05:00     NaN     NaN
2014-01-02 16:10:00     NaN     NaN
...     ...     ...
2014-01-03 08:45:00     NaN     NaN
2014-01-03 08:50:00     NaN     NaN
2014-01-03 08:55:00     NaN     NaN
2014-01-03 09:00:00     NaN     NaN
2014-01-03 09:05:00     NaN     NaN

所有這些 NaN 都應該是最終結果的一部分。 他們在那里只是因為沒有交易時間。 我想避免這種情況。

您可以簡單地使用dropna()丟棄包含 NaN 值的行。

使用您的輸入數據稍作修改的版本進行演示:

                        SPY     AAPL
DateTime                            
2014-01-02 09:30:00  183.91  555.890
2014-01-02 09:31:00  183.89  556.060
2014-01-02 09:32:00  183.90  556.180
2014-01-02 09:33:00  184.00  556.550
2014-01-02 09:34:00  183.98  556.325
2014-01-02 09:45:00  183.89  554.620
2014-01-02 09:46:00  183.83  554.210

直接重采樣給出具有 NaN 值的行:

df.asfreq('5min')

                        SPY    AAPL
DateTime                           
2014-01-02 09:30:00  183.91  555.89
2014-01-02 09:35:00     NaN     NaN
2014-01-02 09:40:00     NaN     NaN
2014-01-02 09:45:00  183.89  554.62

其中 go 與dropna()一起使用:

df.asfreq('5min').dropna()

                        SPY    AAPL
DateTime                           
2014-01-02 09:30:00  183.91  555.89
2014-01-02 09:45:00  183.89  554.62

概述:創建一個區間索引來描述交易時間(工作日的 0930 到 1400)。 然后找到交易 window 中的時間戳(來自重新采樣)。

import pandas as pd

bdate_range = pd.bdate_range(start='2014-01-02', periods=5)
bdate_range

trading_windows = [
    (d + pd.Timedelta('9.5h'), d + pd.Timedelta('16h'))
    for d in bdate_range
]
trading_windows

trading_windows = pd.IntervalIndex.from_tuples(trading_windows)

for t in trading_windows: print(t)

(2014-01-02 09:30:00, 2014-01-02 16:00:00]
(2014-01-03 09:30:00, 2014-01-03 16:00:00]
(2014-01-06 09:30:00, 2014-01-06 16:00:00]
(2014-01-07 09:30:00, 2014-01-07 16:00:00]
(2014-01-08 09:30:00, 2014-01-08 16:00:00]

...並從您的示例中創建了一個 5 分鍾間隔列表(一些在交易時間,其他時間戳在交易停止時)

stamps = [
    '2014-01-02 15:50:00',
    '2014-01-02 15:55:00',
    '2014-01-02 16:00:00',
    '2014-01-02 16:05:00',
    '2014-01-02 16:10:00',
]
stamps = pd.to_datetime(stamps)

然后,我使用間隔索引的.contains()方法來確定時間戳(來自重新采樣)是否在交易 window 期間:

mask = [trading_windows.contains(stamp).any() for stamp in stamps]
stamps[mask]


[3]:
DatetimeIndex(['2014-01-02 15:50:00', '2014-01-02 15:55:00',
               '2014-01-02 16:00:00'],
              dtype='datetime64[ns]', freq=None)

這會保留交易 window 期間的所有時間戳(無論是否有實際交易)。 您可以在“trading_windows”的創建中包含假期。

可能在 5 分鍾頻率處重新采樣以及“最后一個”統計數據必須在您的情況下工作 U 可以將標簽指定為正確的,並在重新采樣中包括右端

最后,您可以在中應用填充以避免時間泄漏

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM