如何优化这个特定的python代码为一个非常大的数据框架?



我从所有比特币价格的大列表开始。我将它导入到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.

我需要的是:

对于每一行在这个数据框中

  1. 取下60个值
  2. 每5个值取下一个60
  3. 每15个值取下一个60
  4. 每60个值取下一个60
  5. 每360个值取下一个60
  6. 在每5760个值中取下一个60
  7. 将这个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值,填补空白,使用扩展,…

相关内容

最新更新