【问题标题】:Is there a possibility for numpy to replace a for-loop for performance improvements?numpy 是否有可能替换 for 循环以提高性能?
【发布时间】:2021-05-17 01:29:31
【问题描述】:

有没有办法用 numpy 或 python 来提高这段代码的性能? 目标是建立一个训练集。 features 是原始数据。我想使用跨步长度为 1 的移动窗口方法来“丰富”数据。最后,我希望将数据从 2D 数组重塑为 3D 数组,因为一个训练输入的形状为 (windowSize, features.shape[1])

import numpy as np

windowSize = 4
features = np.array([[1,2],[3,4],[5,6],[7,8],[9,10],[11,12],[13,14],[15,16],[17,18],[19,20]])
featuresReshaped = features[:windowSize]

for i in range(1, features.shape[0], 1):
    featuresReshaped = np.vstack((featuresReshaped, features[i:i+windowSize]))

maxindex = int(featuresReshaped.shape[0]/windowSize) * windowSize
featuresReshaped = featuresReshaped[:maxindex]
featuresReshaped = featuresReshaped.reshape(int(featuresReshaped.shape[0]/windowSize), windowSize, featuresReshaped.shape[1])

【问题讨论】:

  • 我在底部试了print(featuresReshaped),底部切片(featuresReshaped[-1])稍微打破了移动窗口的模式,应该是这样吗?
  • 使用重复的vstack 很慢。收集列表中的窗口,最后只做一个vstack。可以使用as_strided(或使用它的窗口函数)制作移动窗口view,但后续操作可能会强制复制。
  • @hpaulj 感谢您的回复。我不完全理解。你能给我看一个代码示例吗?

标签: arrays python-3.x numpy optimization dataset


【解决方案1】:

此解决方案通过使用 NumPy 索引来避免所有循环和诸如此类的事情。

import numpy as np

windowSize = 4
features = np.array(
    [[ 1,  2], 
     [ 3,  4],
     [ 5,  6],
     [ 7,  8],
     [ 9, 10],
     [11, 12],
     [13, 14],
     [15, 16],
     [17, 18],
     [19, 20]]
)

indices = np.add.outer(np.arange(len(features) - windowSize + 1), np.arange(windowSize))
# indices:
# [[0 1 2 3]
#  [1 2 3 4]
#  [2 3 4 5]
#  [3 4 5 6]
#  [4 5 6 7]
#  [5 6 7 8]
#  [6 7 8 9]]
features[indices] # indices must be of type np.ndarray or this won't work
# features[indices]:
# [[[ 1  2]
#   [ 3  4]
#   [ 5  6]
#   [ 7  8]]

#  [[ 3  4]
#   [ 5  6]
#   [ 7  8]
#   [ 9 10]]

#  [[ 5  6]
#   [ 7  8]
#   [ 9 10]
#   [11 12]]

#  [[ 7  8]
#   [ 9 10]
#   [11 12]
#   [13 14]]

#  [[ 9 10]
#   [11 12]
#   [13 14]
#   [15 16]]

#  [[11 12]
#   [13 14]
#   [15 16]
#   [17 18]]

#  [[13 14]
#   [15 16]
#   [17 18]
#   [19 20]]]

应该注意的是,您的代码输出的内容与我的不同,我认为这可能是一个错误,因为您的最后一个切片是:

print(featuresReshaped[-1])
# [[15 16]
#  [17 18]
#  [19 20]
#  [17 18]]]

这与您提供的“移动窗口”描述不一致。

【讨论】:

  • 太好了,谢谢!这样它大约快 4756 倍。 :) 我知道。我的实现去掉了最后一部分。你在哪里学会正确使用 numpy?你能指点我一个方向吗? :)
  • @Pm740 很高兴知道它有帮助!我主要是通过经验学习的(我为个人项目和研究做了很多数值计算)。我对“酷 numpy 技巧”有点着迷,所以每次我看到有人用 numpy 做一些有趣的事情(我不明白)时,我总是尝试完全理解代码。我使用的大多数技巧通常是 numpy 索引和广播的某种组合,这在numpy.org/doc/stable/user/basics.indexing.html 中有很好的记录。祝你学习 numpy 好运!
猜你喜欢
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多