python - numpy:以移位的方式将数组相加
问题描述
假设我有一个形状为k*k的n 个数组的输入。现在我想将它们加在一起,但在每次操作后将k*k数组移动一些正整数(步长) 。
很难真正解释它,所以这里有一张小图。
在 k*k 数组相交的每个部分,它们只是被相加。
我目前的实现方式如下:
import numpy as np
# some input with shape (n ,k ,k)
x = np.arange(16).reshape(4 ,2 ,2)
# im intializing the output to zeros in the beginning and
# add the k*k windows to it
out = np.zeros((2 ,5))
# loops over the (n ,k ,k) input and adds the values
# to the output and shifts by 1 to the right
for i in range(4):
# i could also be multipied by any integer to move
# the window by more then one
out[: ,i+0:i+2] += x[i]
所以我的问题是是否有可能摆脱循环,或者您是否可以使用一些内置的 numpy 函数来加速这个或更通用的方法,以便在输入大小增加时使其更快。
感谢您的阅读,祝您有愉快的一天:)
解决方案
我能想到几种方法。最暴力的是创建一个(n, k, k + steps * (n - 1))
数组,然后对第一个轴求和:
steps = ...
n, k, _ = x.shape
buf = np.zeros_like(x, shape=(n, k, k + steps * (n - 1)))
buf[np.arange(n)[:, None, None], np.arange(k)[:, None], np.arange(k) + step * np.arange(n)[:, None, None]] = x
result = buf.sum(0)
我怀疑一个简单的循环会更快,因为你在这里索引浪费了很多空间。
这是一个快速的计时测试:
def index_emplace(x, steps):
k, m, n = x.shape
buf = np.zeros_like(x, shape=(k, m, n + steps * (k - 1)))
r = np.arange(max(x.shape))
a = r[:k][:, None, None]
b = r[:m][:, None]
c = r[:n]
buf[a, b, c + step * a] = x
return buf.sum(0)
def loop_emplace(x, steps):
k, m, n = x.shape
result = np.zeros_like(x, shape=(m, n + steps * (k - 1)))
for i in range(k):
result[:, step * i:step * i + m] += x[i]
return result
x = np.random.randint(10, shape=(100, 100, 100))
steps = 37
%timeit index_emplace(x, steps)
107 ms ± 970 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit loop_emplace(x, steps)
2.26 ms ± 14.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
(index_emplace(x, steps) == loop_emplace(x, steps)).all()
True
如您所见,对于大型数组,循环可以快 50 倍。
推荐阅读
- python - 如何在python中修改OneClassSVM中目标变量的标签
- sql - 过滤具有与 BigQuery 中的条件匹配的所有值的组的简单方法
- mysql - sql查询限制小数
- blackberry - UEM - 如何在应用程序配置中添加动态值
- reactjs - React Native:在哪里执行应用程序初始化?
- javascript - 为什么我的 javascript 重定向不起作用“”?
- javascript - 带有 JSON 换行符的字符串
- ms-word - 如何在 MS word 中编写对话?
- intellij-idea - Intelli-j 构建路径
- python - 图像编码:如何对图像进行注释,以便对强度进行准确加权以进行实例分割