![](/img/trans.png)
[英]Resample Pandas Dataframe with “bin size”/“frequency”
[英]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.