如何以递减方式拉伸特定的numpy数组项?

Posted

技术标签:

【中文标题】如何以递减方式拉伸特定的numpy数组项?【英文标题】:How to stretch specific items of numpy array with decrement? 【发布时间】:2020-09-05 06:31:45 【问题描述】:

给定边界值k,是否有一种矢量化的方式将每个数字n 替换为从n-1k 的连续降序数字?例如,如果 k 为 0,我想将 np.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 的倒数那样能够将整数广播到递减序列而不是最小化它们。

【问题讨论】:

【参考方案1】:

这是另一种使用数组赋值来跳过重复部分的方法 -

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为参数

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])

【讨论】:

所以,numpy 功能中没有隐藏的方法或方法,因为我一直在等待。不过,2 倍的加速要好得多,感谢合作。这帮助我将 itertools.combinations 加速了 1.5 倍!【参考方案2】:

这很简洁,可能会提高效率;我不认为apply 在这里被矢量化,所以你将主要受到原始数组中元素数量的限制(更少,所以它们的值是我的猜测):

import pandas as pd
x = np.array([3,4,2,2,1,3,1])

values = pd.Series(x).apply(lambda val: np.arange(val-1,-1,-1)).values
output = np.concatenate(values)

【讨论】:

以上是关于如何以递减方式拉伸特定的numpy数组项?的主要内容,如果未能解决你的问题,请参考以下文章

html页面比较长,body里的background图片比较短,如何设置属性使图片以拉伸方式占满页面?

html页面比较长,body里的background图片比较短,如何设置属性使图片以拉伸方式占满页面?

如何将 WPF 选项卡项标题拉伸到父控件宽度

根据条件以编程方式拉伸 UIButton 宽度

选择 stackView 上的哪个子视图将拉伸(以编程方式)

垂直拉伸不按打印项高度分页