gpt4 book ai didi

numpy - 在 numpy 中创建倾斜/连续移位矩阵的最快方法

转载 作者:行者123 更新时间:2023-12-04 08:07:24 25 4
gpt4 key购买 nike

我需要创建一个如下所示的 (w,N)-矩阵:

w//2............N-1,N-1
. \ N-1
. \ N-1
. \ N-1
1...............N-1,N-1
0...................N-1
00..................N-2
. \ N-3
. \ .
. \ .
000000..............N-w//2
这是一个 (w,N) 矩阵,具有奇数 w。中间行是从 0 到 N 的范围。对于中间行上方的每个行索引,该行向左移动,就像 scipy.ndimage.shift(mode='nearest') 对于中间行下方的每一行,它使用相同的方法向右移动。
N 通常在 10^4 左右,w 通常在 10 到 10^2 之间。
我想出了两种方法来做到这一点:
from scipy.ndimage import shift
middle = np.arange(0, N)
final = np.vstack(
[shift(middle, i, mode='nearest') for i in range(-w//2, 0)] +
[middle] +
[shift(middle, i, mode='nearest') for i in range(1, w//2)] )
需要 0.035秒运行。
np.vstack([
np.maximum(
0,
np.minimum(
N-1,
np.arange(-step, N-step)
)
)
for step in range(-w//2, w//2)
])
需要 0.021秒运行。
这些数字是 N=10^3 和 w=21。
我真的很想让这些数字尽可能低,最好降到 1 毫秒左右。
我尝试了多处理,但这并没有真正的帮助,开销太大而无法从并发中获得一些东西。我也知道我可以将这个结果存储在某个地方,但这需要这个函数的调用者进行重大更改,所以稍后会完成。
是否有任何数学关系可以表示这样的倾斜/移位操作?我想不出一个,但如果有,numpy 可能会利用它来击败我的结果。
所以是的,有什么想法可以让我的代码更快吗?

最佳答案

使用来自 0 的适当形状和水平值初始化数组至 N (包括的)

w, N = 11, 10
arr = np.empty(shape= [w, N], dtype= int)

arr[:] = np.arange(N)
arr

>>> [[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]]
从每一行中减去一个合适的值
arr += np.arange(w).reshape([-1, 1])[::-1] - (1+w//2)
arr

>>> [[ 5., 6., 7., 8., 9., 10., 11., 12., 13., 14.],
[ 4., 5., 6., 7., 8., 9., 10., 11., 12., 13.],
[ 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.],
[ 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.],
[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[-1., 0., 1., 2., 3., 4., 5., 6., 7., 8.],
[-2., -1., 0., 1., 2., 3., 4., 5., 6., 7.],
[-3., -2., -1., 0., 1., 2., 3., 4., 5., 6.],
[-4., -3., -2., -1., 0., 1., 2., 3., 4., 5.],
[-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.]]
其中值越过极限值重新分配给他们极限值
arr[arr<0] = 0
arr[arr>N-1] = N-1

arr

>>> [[5., 6., 7., 8., 9., 9., 9., 9., 9., 9.],
[4., 5., 6., 7., 8., 9., 9., 9., 9., 9.],
[3., 4., 5., 6., 7., 8., 9., 9., 9., 9.],
[2., 3., 4., 5., 6., 7., 8., 9., 9., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9., 9.],
[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[0., 0., 1., 2., 3., 4., 5., 6., 7., 8.],
[0., 0., 0., 1., 2., 3., 4., 5., 6., 7.],
[0., 0., 0., 0., 1., 2., 3., 4., 5., 6.],
[0., 0., 0., 0., 0., 1., 2., 3., 4., 5.],
[0., 0., 0., 0., 0., 0., 1., 2., 3., 4.]]

Edit


尝试计时脚本
import timeit

script = '''
w, N = 21, 10**3
arr = np.empty(shape= [w, N], dtype= int)
arr[:] = np.arange(N)
arr += np.arange(w).reshape([-1, 1])[::-1] - (1+w//2)

arr[arr<0] = 0
arr[arr>N-1] = N-1
'''

time = timeit.timeit(script, number= 100000, setup= 'import numpy as np') / 100000

time

>>> 0.00019059010320999733 # 0.19 ms

关于numpy - 在 numpy 中创建倾斜/连续移位矩阵的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66158868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com