Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多个开始和停止值的矢量化NumPy linspace_Python_Numpy_Multidimensional Array_Vectorization_Array Broadcasting - Fatal编程技术网

Python 多个开始和停止值的矢量化NumPy linspace

Python 多个开始和停止值的矢量化NumPy linspace,python,numpy,multidimensional-array,vectorization,array-broadcasting,Python,Numpy,Multidimensional Array,Vectorization,Array Broadcasting,我需要创建一个二维数组,其中每一行的开始和结束可能有不同的数字。假设给出了每行的第一个和最后一个元素,所有其他元素只是根据行的长度进行插值。在一个简单的情况下,假设我想创建一个3X3数组,该数组的起点相同,但终点不同,由下面的W给出: array([[ 0., 1., 2.], [ 0., 2., 4.], [ 0., 3., 6.]]) 有没有比以下方法更好的方法: D=np.ones((3,3))*np.arange(0,3) D=D/D[:,-1]

我需要创建一个二维数组,其中每一行的开始和结束可能有不同的数字。假设给出了每行的第一个和最后一个元素,所有其他元素只是根据行的长度进行插值。在一个简单的情况下,假设我想创建一个3X3数组,该数组的起点相同,但终点不同,由下面的W给出:

array([[ 0.,  1.,  2.],
       [ 0.,  2.,  4.],
       [ 0.,  3.,  6.]])
有没有比以下方法更好的方法:

D=np.ones((3,3))*np.arange(0,3)
D=D/D[:,-1] 
W=np.array([2,4,6]) # last element of each row assumed given
Res= (D.T*W).T  
这里有一种使用-

样本运行-

In [22]: # Setup start, stop for each row and no. of elems in each row
    ...: start = np.array([1,4,2])
    ...: stop  = np.array([6,7,6])
    ...: N = 5
    ...: 

In [23]: create_ranges(start, stop, 5)
Out[23]: 
array([[ 1.  ,  2.25,  3.5 ,  4.75,  6.  ],
       [ 4.  ,  4.75,  5.5 ,  6.25,  7.  ],
       [ 2.  ,  3.  ,  4.  ,  5.  ,  6.  ]])

In [24]: create_ranges(start, stop, 5, endpoint=False)
Out[24]: 
array([[ 1. ,  2. ,  3. ,  4. ,  5. ],
       [ 4. ,  4.6,  5.2,  5.8,  6.4],
       [ 2. ,  2.8,  3.6,  4.4,  5.2]])
让我们利用多核! 我们可以利用大量数据,提高内存效率,从而提高性能-

import numexpr as ne

def create_ranges_numexpr(start, stop, N, endpoint=True):
    if endpoint==1:
        divisor = N-1
    else:
        divisor = N
    s0 = start[:,None]
    s1 = stop[:,None]
    r = np.arange(N)
    return ne.evaluate('((1.0/divisor) * (s1 - s0))*r + s0')

与OP的类似,
linspace
的这种使用假设所有行的起始值都是0

x=np.linspace(0,1,N)[:,None]*np.arange(0,2*N,2)
(编辑-这是我应该得到的内容的转置;或者转置它,或者切换使用
[:,None]

对于N=3000,其速度明显快于
@Divaker的
解决方案。我不完全清楚为什么

In [132]: timeit N=3000;x=np.linspace(0,1,N)[:,None]*np.arange(0,2*N,2)
10 loops, best of 3: 91.7 ms per loop
In [133]: timeit create_ranges(np.zeros(N),np.arange(0,2*N,2),N)
1 loop, best of 3: 197 ms per loop
In [134]: def foo(N):
     ...:     D=np.ones((N,N))*np.arange(N)
     ...:     D=D/D[:,-1]
     ...:     W=np.arange(0,2*N,2)
     ...:     return (D.T*W).T
     ...: 
In [135]: timeit foo(3000)
1 loop, best of 3: 454 ms per loop
============

对于启动和停止,我可以使用:

In [201]: starts=np.array([1,4,2]); stops=np.array([6,7,8])
In [202]: x=(np.linspace(0,1,5)[:,None]*(stops-starts)+starts).T
In [203]: x
Out[203]: 
array([[ 1.  ,  2.25,  3.5 ,  4.75,  6.  ],
       [ 4.  ,  4.75,  5.5 ,  6.25,  7.  ],
       [ 2.  ,  3.5 ,  5.  ,  6.5 ,  8.  ]])
额外的计算使它比创建范围要慢一些

In [208]: timeit N=3000;starts=np.zeros(N);stops=np.arange(0,2*N,2);x=(np.linspace(0,1,N)[:,None]*(stops-starts)+starts).T
1 loop, best of 3: 227 ms per loop

所有这些解决方案都只是在
开始
停止
之间进行线性插值的想法的变体。我基于@Divakar的解决方案扩展了一些功能。它牺牲了一些速度,但现在可以兼容不同长度的
N
,而不仅仅是标量。另外,这个版本比以前快

NumPy>=1.16.0: 现在可以为的
start
stop
参数提供类似数组的值

对于问题中给出的示例,语法为:

>>> np.linspace((0, 0, 0), (2, 4, 6), 3, axis=1)
array([[0., 1., 2.],
       [0., 2., 4.],
       [0., 3., 6.]])
新的
参数指定生成数据的方向。默认情况下,它是
0

>>> np.linspace((0, 0, 0), (2, 4, 6), 3)
array([[0., 0., 0.],
       [1., 2., 3.],
       [2., 4., 6.]])

如果您想使用pandas:
pd.Series(W).apply(lambda e:np.linspace(0,e,3))
基本上您有两个向量(矩阵的第一列和最后一列),对吗?然后你想为每一行插入一些值。@dayum如果你想改变起始位置,方法是一样的,但是你用两个向量start和stop构建一个df,然后再次调用apply,lambda参数是df.start,df.end,3为什么不利用
linspace
?@Divakar我的意思是不在这里搜索循环,我对numpy不太熟练,太多偏见,但我想知道是否有一种方法可以在numpy中以某种方式广播该函数?@Boud Well有
np。沿_轴应用
,但这不是为了性能。对于NumPy阵列而言,广播元素实际上提供了性能。
@Boud
,Saullo在
linspace
上的迭代非常清晰,可能是我一时冲动使用的。但我不会把它做得比必要的更花哨。对于大型数组,Divakar的回答仅比OP快2倍。由于问题说明“给出了每行的第一个和最后一个元素”,您将如何将每行的开始和停止值合并到基于
linspace
的解决方案中?
>>> np.linspace((0, 0, 0), (2, 4, 6), 3, axis=1)
array([[0., 1., 2.],
       [0., 2., 4.],
       [0., 3., 6.]])
>>> np.linspace((0, 0, 0), (2, 4, 6), 3)
array([[0., 0., 0.],
       [1., 2., 3.],
       [2., 4., 6.]])