猿问

在2D数组上放置列表元素的快速方法

我有两个列表,两个列表都称为位置和值。位置和值的每个子列表包含2D数组中在时间k = 1,..,n处的峰的位置和值。例如


values    = [[5,1,1,8,10],[3,1,7,9,4]]

positions = [[(0,0),(1,2),(1,4),(3,3),(4,4)],[(0,1),(1,3),(2,4),(3,4),(4,0)]]

在此,列表[5,1,1,8,10]是2D数组上的值,[[0,0),(1,2),(1,4),(3,3),(4 ,, 4)]是这些值在时间0处的对应位置。同样,[3,1,7,9,4]是2D数组上的值,[[0,1),(1,3),(2,4),(3,4),(4,0 )]是这些值在时间1的对应位置。我想将这些值放在2D零数组上的对应位置。所以我做了以下功能


import itertools


def list_to_array(n_1, n_2, positions, values):


    new_array_list = []


    for k in range(len(positions)):


        A = np.zeros((n_1,n_2))


        for i, j in itertools.product(range(n_1), range(n_2)):


            if (i,j) in positions[k]:


                X = positions[k].index((i,j))

                A[i,j] = values[k][X]


        new_array_list += [A]


    return new_array_list

这应该返回两个数组


A[0] = [[  5.   0.   0.   0.   0.]

 [  0.   0.   1.   0.   1.]

 [  0.   0.   0.   0.   0.]

 [  0.   0.   0.   8.   0.]

 [  0.   0.   0.   0.  10.]]


A[1] = [[ 0.  3.  0.  0.  0.]

 [ 0.  0.  0.  1.  0.]

 [ 0.  0.  0.  0.  7.]

 [ 0.  0.  0.  0.  9.]

 [ 4.  0.  0.  0.  0.]]

对于256x256的数组,单次迭代大约需要一秒钟,因此我需要对1600个列表执行迭代,这虽然很长,但仍然很合理。但是,我也希望对较大的数组(每个方向的长度最多8倍)执行此操作,因此很明显,上面的代码将花费太长的时间。我想知道是否有人知道更快的方法?


SMILET
浏览 145回答 2
2回答

眼眸繁星

您可以使用专家库。在这种情况下,NumPy提供了矢量化解决方案。对于较大的数字数据结构,列表列表方法效率低下,因为它将使用指针的集合。取而代之的是,NumPy利用连续的存储块来实现有效的数值转换。import numpy as npvalues    = [[5,1,1,8,10],[3,1,7,9,4]]positions = [[(0,0),(1,2),(1,4),(3,3),(4,4)],[(0,1),(1,3),(2,4),(3,4),(4,0)]]# convert to NumPy arrays of shapes (10,) and (10, 2)      val = np.array(values).flatten()pos = np.array(positions).reshape(-1, 2)# initialize array of zerosarr = np.zeros(pos.max(0)+1)# assign values to positionsarr[[*pos.T]] = valprint(arr)array([[  5.,   3.,   0.,   0.,   0.],       [  0.,   0.,   1.,   1.,   1.],       [  0.,   0.,   0.,   0.,   7.],       [  0.,   0.,   0.,   8.,   9.],       [  4.,   0.,   0.,   0.,  10.]])如果根据您的更新,您需要2个单独的阵列,则可以重复此过程:# convert to NumPy arrays of shapes (10,) and (10, 2)      val1, val2 = (np.array(v).flatten() for v in values)pos1, pos2 = (np.array(p).reshape(-1, 2) for p in positions)# initialize array of zerosarr1 = np.zeros(pos1.max(0)+1)arr2 = np.zeros(pos2.max(0)+1)# assign values to positionsarr1[[*pos1.T]] = val1arr2[[*pos2.T]] = val2

侃侃尔雅

您可以这样做:import itertoolsimport numpy as npdef list_to_array(n_1, n_2, positions, values):    new_array_list = []    for k in range(len(positions)):        A = np.zeros((n_1,n_2))        for i in range(len(positions[k])):            A[positions[k][i]] = values[k][i]        new_array_list += [A]    return new_array_listvalues    = [[5,1,1,8,10],[3,1,7,9,4]]positions = [[(0,0),(1,2),(1,4),(3,3),(4,4)],[(0,1),(1,3),(2,4),(3,4),(4,0)]]print list_to_array(5,5,positions,values)
随时随地看视频慕课网APP

相关分类

Python
我要回答