我从所有比特币价格的大列表开始。我将它导入到Dataframe中。
df.head ()
BTC-USDT_close
open_time
2021-11-05 22:28:00 61151.781250
2021-11-05 22:27:00 61199.011719
2021-11-05 22:26:00 61201.398438
2021-11-05 22:25:00 61237.828125
2021-11-05 22:24:00 61195.578125
...
221651 rows total.
我需要的是:
对于每一行在这个数据框中
- 取下60个值
- 每5个值取下一个60
- 每15个值取下一个60
- 每60个值取下一个60
- 每360个值取下一个60
- 在每5760个值中取下一个60
- 将这个60行的新表作为数组添加到列表
所以最后我想要有很多这样的
small_df.head (6)
BTC-USDT_1m BTC-USDT_5m BTC-USDT_15m BTC-USDT_1h BTC-USDT_6h BTC-USDT_4d
0 61199.011719 61199.011719 61199.011719 61199.011719 61199.011719 61199.011719
1 61201.398438 61241.390625 61159.578125 61079.800781 60922.968750 60968.320312
2 61237.828125 61309.000000 61063.628906 60845.710938 61682.960938 60717.500000
3 61195.578125 61159.578125 61100.000000 61060.000000 62191.000000 60939.210938
4 61221.179688 61165.371094 61079.800781 61220.011719 61282.000000 65934.328125
5 61241.390625 61047.488281 61175.238281 60812.210938 61190.300781 60599.000000
...
60 rows total
(基本上这些是不同时间框架内60个先前值的序列)
所以代码如下:
seq_list = []
for i in range(len(df) // 2):
r = i+1
small_df = pd.DataFrame()
small_df['BTC-USDT_1m'] = df['BTC-USDT_close'][r:r+seq_len:1].reset_index(drop=True)
small_df['BTC-USDT_5m'] = df['BTC-USDT_close'][r:(r+seq_len)*5:5].dropna().reset_index(drop=True)
small_df['BTC-USDT_15m'] = df['BTC-USDT_close'][r:(r+seq_len)*15:15].dropna().reset_index(drop=True)
small_df['BTC-USDT_1h'] = df['BTC-USDT_close'][r:(r+seq_len)*60:60].dropna().reset_index(drop=True)
small_df['BTC-USDT_6h'] = df['BTC-USDT_close'][r:(r+seq_len)*360:360].dropna().reset_index(drop=True)
small_df['BTC-USDT_4d'] = df['BTC-USDT_close'][r:(r+seq_len)*5760:5760].dropna().reset_index(drop=True)
seq_list.append([small_df, df['target'][r]])
你可以想象,它非常慢,每分钟可以做1500个序列,所以整个过程需要12个小时。
你能告诉我一种加快速度的方法吗?提前感谢!
您不能通过索引来完成此操作,因为这会创建大型索引并且效率低下。相反,您可以使用.rolling()
来创建滚动窗口。
您可以在文档中看到,滚动还支持在时间戳上滚动窗口。查看结果:
>>> df_time.rolling('2s').sum()
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 3.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 4.0
在您的示例中,您可以执行以下操作
small_df['BTC-USDT_1m'] = df['BTC-USDT_close'].rolling("1m").mean().reset_index(drop=True)
第一个参数总是窗口的大小,即从df
中获取的样本数量。这可以是一个整数,表示样本的确切数量,也可以是一个时间戳,以便根据固定的时间框架遍历表。
在这种情况下,它将计算基于1分钟移动窗口的平均价格。
这将比你的基于索引的解决方案更准确,因为在那里你没有考虑到时间戳之间的距离,而且你实际上只是采取单个值,这意味着你高度依赖于当地的波动。给定窗口大小上的平均值为您提供了该时间段内价格的平均变化。
然而,如果你只想要给定尺寸的单一价格,那么你只需使用一个小窗口,如
small_df['BTC-USDT_1m'] = df['BTC-USDT_close'].rolling(1, step=60).reset_index(drop=True)
这里的step
参数使移动窗口不考虑每一个元素,而是在每次取值时移动60
样本。
任何像你的解决方案或后者的步骤,当然,产生许多不同于原来的新样本,因此你必须考虑如果你想放弃NaN值,填补空白,使用扩展,…