如何以递减方式拉伸特定的numpy数组项?
Posted
技术标签:
【中文标题】如何以递减方式拉伸特定的numpy数组项?【英文标题】:How to stretch specific items of numpy array with decrement? 【发布时间】:2020-09-05 06:31:45 【问题描述】:给定边界值k
,是否有一种矢量化的方式将每个数字n
替换为从n-1
到k
的连续降序数字?例如,如果 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.repeat
和 np.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图片比较短,如何设置属性使图片以拉伸方式占满页面?