首页 > 解决方案 > 如何以递减方式拉伸特定的numpy数组项?

问题描述

给定边界值k,是否有一种矢量化方法可以将每个数字替换为从ton的连续降序数字?例如,如果是 0,我想用. 输入数组的每一项都大于。n-1kknp.array([3,4,2,2,1,3,1])np.array([2,1,0,3,2,1,0,1,0,1,0,0,2,1,0,0])k

我已经尝试过组合,np.repeatnp.cumsum它似乎是回避的解决方案:

x = np.array([3,4,2,2,1,3,1])
y = np.repeat(x, x)
t = -np.ones(y.shape[0])
t[np.r_[0, np.cumsum(x)[:-1]]] = x-1
np.cumsum(t)

还有其他方法吗?我希望类似的倒数np.add.reduceat能够将整数广播到递减序列而不是最小化它们。

标签: pythonarraysnumpy

解决方案


这是数组分配跳过重复部分的另一种方法 -

def func1(a):
    l = a.sum()
    out = np.full(l, -1, dtype=int)
    out[0] = a[0]-1
    idx = a.cumsum()[:-1]
    out[idx] = a[1:]-1
    return out.cumsum()

基准测试

# OP's soln
def OP(x):
    y = np.repeat(x, x)
    t = -np.ones(y.shape[0], dtype=int)
    t[np.r_[0, np.cumsum(x)[:-1]]] = x-1
    return np.cumsum(t)

使用benchit包(几个基准测试工具打包在一起;免责声明:我是它的作者)对建议的解决方案进行基准测试。

import benchit

a = np.array([3,4,2,2,1,3,1])
in_ = [np.resize(a,n) for n in [10, 100, 1000, 10000]]
funcs = [OP, func1]
t = benchit.timings(funcs, in_)
t.plot(logx=True, save='timings.png')

在此处输入图像描述

扩展k为 arg

def func1(a, k):
    l = a.sum()+len(a)*(-k)
    out = np.full(l, -1, dtype=int)
    out[0] = a[0]-1
    idx = (a-k).cumsum()[:-1]
    out[idx] = a[1:]-1-k
    return out.cumsum()

样品运行 -

In [120]: a
Out[120]: array([3, 4, 2, 2, 1, 3, 1])

In [121]: func1(a, k=-1)
Out[121]: 
array([ 2,  1,  0, -1,  3,  2,  1,  0, -1,  1,  0, -1,  1,  0, -1,  0, -1,
        2,  1,  0, -1,  0, -1])

推荐阅读