pandas 如何为一个非常大的DataFrame优化这个特定的python代码?

9rygscc1  于 2022-12-16  发布在  Python
关注(0)|答案(1)|浏览(116)

我从一个包含所有比特币价格的大列表开始,将它导入到一个数据框架中。
df.标题()

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.

我需要的是以下内容:
对于此 Dataframe 中的每行
1.取下60个值
1.每5个值取下60
1.在每15个值中取下60
1.在每60个值中取下一个60
1.在每360个值中取下一个60
1.在每5760个值中取下一个60
1.将此60行的新表作为数组添加到列表中
所以最后我想有很多这样的:
小尺寸股骨头(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个小时。
你能告诉我一个加快速度的方法吗?
先谢了!

ymzxtsji

ymzxtsji1#

你不能通过索引来实现,因为这会创建很大的索引,效率很低,相反,你可以使用.rolling()来创建滚动窗口。
你可以在documentation中看到,滚动也支持在时间戳上滚动窗口。

>>> 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样本。
当然,任何解决方案(如您的解决方案或带有step的解决方案)都会产生许多与原始样本不同的新样本,因此您必须考虑是否要删除NaN值、填充空白、使用expand ...

相关问题