Python 添加/提取列表元素的有效方法

Python 添加/提取列表元素的有效方法,python,arrays,list,numpy,vectorization,Python,Arrays,List,Numpy,Vectorization,假设我有以下列表: rays_all = [np.array(r11, r21, r31, r41), np.array(r12, r22, r32, r42), np.array(r13, r23, r33, r43), np.array(r14, r24, r34, r44)] 所有r11、r21、r31等都是具有形状(3L、)的阵列(将其视为三维空间中的向量) 如果我想提取np.array(r14,r24,r34,r

假设我有以下列表:

rays_all = [np.array(r11, r21, r31, r41),
            np.array(r12, r22, r32, r42),
            np.array(r13, r23, r33, r43),
            np.array(r14, r24, r34, r44)]
所有r11、r21、r31等都是具有形状(3L、)的阵列(将其视为三维空间中的向量)

如果我想提取
np.array(r14,r24,r34,r44)
的(4L,3L)数组,我只需使用
rays\u all[-1]
。如果我想附加一个新的
np.array数组(r15,r25,r35,r45)
,我只需要使用
rays\u all.append

现在我以另一种方式排列上述向量(r11、r12等):

ray1 = [r11, r12, r13, r14]
ray2 = [r21, r22]
ray3 = [r31, r32, r33]
ray4 = [r41, r42, r43, r44]
每个“光线”现在都有自己的长度不同的列表。如果要提取数组结构中每个列表的最后一个元素,即
np.array([r14,r22,r33,r44])
,最有效的方法是什么?另一方面,如果我想将数组
np.array([r15,r23,r34,r45])
中的元素添加到列表中,那么

ray1 = [r11, r12, r13, r14, r15]
ray2 = [r21, r22, r23]
ray3 = [r31, r32, r33, r34]
ray4 = [r41, r42, r43, r44, r45]

最有效的方法是什么?我知道我只需要一个循环就可以做到这一点,但我想它比
rays\u all[-1]
rays\u append()
要慢得多?有没有“矢量化”的方法可以做到这一点?

在混合数组和列表操作时要小心

制作一些3元素数组,并像第一种情况那样组合它们:

In [748]: r1,r2,r3,r4=np.arange(3),np.ones(3),np.zeros(3),np.arange(3)[::-1]
In [749]: x1=np.array((r1,r2))
In [750]: x2=np.array((r3,r4))
In [751]: rays=[x1,x2]
In [752]: rays
Out[752]: 
[array([[ 0.,  1.,  2.],
        [ 1.,  1.,  1.]]), array([[ 0.,  0.,  0.],
        [ 2.,  1.,  0.]])]
射线
现在是一个包含两个二维数组((2,3)形状)的列表。正如您所说,您可以从该列表中选择一个项目或向其附加另一个数组(您可以向其附加任何内容,而不仅仅是一个类似的数组)。
射线的操作是列表操作

您还可以创建三维阵列:

In [758]: ray_arr=np.array((x1,x2))
In [759]: ray_arr
Out[759]: 
array([[[ 0.,  1.,  2.],
        [ 1.,  1.,  1.]],

       [[ 0.,  0.,  0.],
        [ 2.,  1.,  0.]]])
In [760]: ray_arr.shape
Out[760]: (2, 2, 3)
In [761]: ray_arr[-1]
Out[761]: 
array([[ 0.,  0.,  0.],
       [ 2.,  1.,  0.]])
与列表一样,您可以从
ray\u arr
中进行选择。但是追加需要通过
np.concatenate
(可能隐藏在
np.append
函数中)创建一个新数组。列表上没有“就地”追加

通过在最后一个维度上建立索引,有效地选择所有组件数组的最后一个元素

In [762]: ray_arr[:,:,-1]
Out[762]: 
array([[ 2.,  1.],
       [ 0.,  0.]])
要从列表
射线
中获取相应的值,必须使用列表理解(或其他循环):

没有像数组那样的索引快捷方式

有像
zip
(以及
itertools
中的其他工具)这样的工具可以帮助您迭代列表,甚至重新排列值,例如

In [773]: list(zip(['a','b'],['c','d']))
Out[773]: [('a', 'c'), ('b', 'd')]
In [774]: list(zip(['a','b'],['c','d']))[-1]
Out[774]: ('b', 'd')
还有参差不齐的子列表:

In [782]: list(zip(['a','b','c'],['d']))
Out[782]: [('a', 'd')]
In [783]: list(itertools.zip_longest(['a','b','c'],['d']))
Out[783]: [('a', 'd'), ('b', None), ('c', None)]
但我看不出这些对从光线向量中提取值有什么帮助


值得探索的是将基本向量收集到一个2d数组中,并将索引用于各种用途的额外组

In [867]: allrays=np.array([r1,r2,r3,r4])
In [868]: allrays
Out[868]: 
array([[ 0.,  1.,  2.],
       [ 1.,  1.,  1.],
       [ 0.,  0.,  0.],
       [ 2.,  1.,  0.]])
所有光线的“z”坐标

In [869]: allrays[:,-1]
Out[869]: array([ 2.,  1.,  0.,  0.])
光线的一个子集(因为它是一个切片,所以它是一个视图)

另一个子集:

In [872]: allrays[2:,:]
Out[872]: 
array([[ 0.,  0.,  0.],
       [ 2.,  1.,  0.]])
3项子集,通过列表选择-这是一个副本

In [873]: allrays[[0,1,2],:]
Out[873]: 
array([[ 0.,  1.,  2.],
       [ 1.,  1.,  1.],
       [ 0.,  0.,  0.]])
In [874]: allrays[[3],:]
Out[874]: array([[ 2.,  1.,  0.]])
通过索引获得的若干子集:

In [875]: ind=[[0,1,2],[3]]
In [876]: [allrays[i] for i in ind]
Out[876]: 
[array([[ 0.,  1.,  2.],
        [ 1.,  1.,  1.],
        [ 0.,  0.,  0.]]), 
 array([[ 2.,  1.,  0.]])]
如果组是连续的,则可以使用
拆分

In [884]: np.split(allrays,[3])
Out[884]: 
[array([[ 0.,  1.,  2.],
        [ 1.,  1.,  1.],
        [ 0.,  0.,  0.]]), array([[ 2.,  1.,  0.]])]
子阵列是视图(请使用
。\uuuuu数组\u接口\uuuu
属性进行检查)

实际上,它只是将不规则列表问题提高了一个级别。不过,它还有更多的灵活性。您可以构建其他索引子列表,例如

In [877]: ind1=[i[-1] for i in ind]   # last of all groups
In [878]: ind1
Out[878]: [2, 3]
In [879]: ind2=[i[0] for i in ind]   # first of all groups
In [880]: ind2
Out[880]: [0, 3]
您可以将一些新值连接到
allray
。然后您可能需要重建索引列表。但我怀疑这种构建是在重复访问时完成的



关于访问由
plt.pcolormesh
(和
plt.pcolor
)生成的
img
中的值的前面的SO问题我想到了。一个将图像作为二维网格上的曲面进行维护,另一个更一般,只是四边形的集合,每个四边形都有一个颜色和路径定义其边界。

在混合数组和列表操作时要小心

制作一些3元素数组,并像第一种情况那样组合它们:

In [748]: r1,r2,r3,r4=np.arange(3),np.ones(3),np.zeros(3),np.arange(3)[::-1]
In [749]: x1=np.array((r1,r2))
In [750]: x2=np.array((r3,r4))
In [751]: rays=[x1,x2]
In [752]: rays
Out[752]: 
[array([[ 0.,  1.,  2.],
        [ 1.,  1.,  1.]]), array([[ 0.,  0.,  0.],
        [ 2.,  1.,  0.]])]
rays
现在是一个包含两个2d数组((2,3)形状)的列表。正如您所说,您可以从该列表中选择一个项目或向其附加另一个数组(您可以向其附加任何内容,而不仅仅是一个类似的数组)。
rays
的操作是列表操作

您还可以创建三维阵列:

In [758]: ray_arr=np.array((x1,x2))
In [759]: ray_arr
Out[759]: 
array([[[ 0.,  1.,  2.],
        [ 1.,  1.,  1.]],

       [[ 0.,  0.,  0.],
        [ 2.,  1.,  0.]]])
In [760]: ray_arr.shape
Out[760]: (2, 2, 3)
In [761]: ray_arr[-1]
Out[761]: 
array([[ 0.,  0.,  0.],
       [ 2.,  1.,  0.]])
您可以使用列表从
ray\u arr
中进行选择。但是追加需要通过
np.concatenate
(可能隐藏在
np.append
函数中)创建一个新数组。列表上没有“就地”追加

通过在最后一个维度上建立索引,有效地选择所有组件数组的最后一个元素

In [762]: ray_arr[:,:,-1]
Out[762]: 
array([[ 2.,  1.],
       [ 0.,  0.]])
要从列表
射线
中获取相应的值,必须使用列表理解(或其他循环):

没有像数组那样的索引快捷方式

有像
zip
(以及
itertools
中的其他工具)这样的工具可以帮助您迭代列表,甚至重新排列值,例如

In [773]: list(zip(['a','b'],['c','d']))
Out[773]: [('a', 'c'), ('b', 'd')]
In [774]: list(zip(['a','b'],['c','d']))[-1]
Out[774]: ('b', 'd')
还有参差不齐的子列表:

In [782]: list(zip(['a','b','c'],['d']))
Out[782]: [('a', 'd')]
In [783]: list(itertools.zip_longest(['a','b','c'],['d']))
Out[783]: [('a', 'd'), ('b', None), ('c', None)]
但我看不出这些对从光线向量中提取值有什么帮助


值得探索的是将基本向量收集到一个2d数组中,并将索引用于各种用途的额外组

In [867]: allrays=np.array([r1,r2,r3,r4])
In [868]: allrays
Out[868]: 
array([[ 0.,  1.,  2.],
       [ 1.,  1.,  1.],
       [ 0.,  0.,  0.],
       [ 2.,  1.,  0.]])
所有光线的“z”坐标

In [869]: allrays[:,-1]
Out[869]: array([ 2.,  1.,  0.,  0.])
光线的一个子集(因为它是一个切片,所以它是一个视图)

另一个子集:

In [872]: allrays[2:,:]
Out[872]: 
array([[ 0.,  0.,  0.],
       [ 2.,  1.,  0.]])
3项子集,通过列表选择-这是一个副本

In [873]: allrays[[0,1,2],:]
Out[873]: 
array([[ 0.,  1.,  2.],
       [ 1.,  1.,  1.],
       [ 0.,  0.,  0.]])
In [874]: allrays[[3],:]
Out[874]: array([[ 2.,  1.,  0.]])
通过索引获得的若干子集:

In [875]: ind=[[0,1,2],[3]]
In [876]: [allrays[i] for i in ind]
Out[876]: 
[array([[ 0.,  1.,  2.],
        [ 1.,  1.,  1.],
        [ 0.,  0.,  0.]]), 
 array([[ 2.,  1.,  0.]])]
如果组是连续的,则可以使用
拆分

In [884]: np.split(allrays,[3])
Out[884]: 
[array([[ 0.,  1.,  2.],
        [ 1.,  1.,  1.],
        [ 0.,  0.,  0.]]), array([[ 2.,  1.,  0.]])]
子阵列是视图(请使用
。\uuuuu数组\u接口\uuuu
属性进行检查)

实际上,它只是将不规则列表问题提高了一个级别。不过,它还有更多的灵活性。您可以构建其他索引子列表,例如

In [877]: ind1=[i[-1] for i in ind]   # last of all groups
In [878]: ind1
Out[878]: [2, 3]
In [879]: ind2=[i[0] for i in ind]   # first of all groups
In [880]: ind2
Out[880]: [0, 3]
您可以将一些新值连接到
allray
。然后您可能需要重建索引列表。但我怀疑这种构建是在重复访问时完成的


我想到了一个关于从
plt.pcolormesh
(和
plt.pcolor
)生成的
img
中访问值的早期SO问题。一个将图像作为二维网格上的曲面进行维护,另一个更一般地说,只是四边形的集合,每个四边形都具有颜色和路径定义