如何使用减量拉伸numpy数组的特定项?

2024-09-27 07:25:17 发布

您现在位置:Python中文网/ 问答频道 /正文

给定边界值k,是否有一种矢量化的方法将每个数n替换为从n-1k的连续降序数?例如,如果k为0,我想用np.array([2,1,0,3,2,1,0,1,0,1,0,0,2,1,0,0])替换np.array([3,4,2,2,1,3,1])。输入数组的每一项都大于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的类似smth的逆函数能够将整数广播到递减序列,而不是最小化它们


Tags: 方法addnpones数组解决方案array矢量化
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)

下面是另一种通过数组赋值跳过重复部分的方法-

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)

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

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

enter image description here

扩展以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])

相关问题 更多 >

    热门问题