假设我有以下列表:
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,)的数组(将其视为3D空间中的矢量)。
如果我想提取np.array(r14, r24, r34, r44)
的(4L,3L)数组,我只需使用rays_all[-1]
。如果我想追加np.array(r15, r25, r35, r45)
的新数组,我只需使用rays_all.append
。
现在我以另一种方式安排上述向量(r11,r12等):
ray1 = [r11, r12, r13, r14]
ray2 = [r21, r22]
ray3 = [r31, r32, r33]
ray4 = [r41, r42, r43, r44]
每个' ray'现在有自己的不同长度的列表。如果我想提取数组结构中每个列表的最后一个元素,即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_all[-1]
和rays_append()
慢得多?有没有矢量化'这样做的方式?
答案 0 :(得分:1)
小心混合数组和列表操作。
制作一些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
的操作是列表操作。
您还可以创建一个3d数组:
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_arr
。但附加需要通过np.concatenate
创建一个新数组(可能隐藏在np.append
函数中)。没有'就地'附在列表上。
通过索引最后一个维度,有效选择所有组件数组的最后一个元素。
In [762]: ray_arr[:,:,-1]
Out[762]:
array([[ 2., 1.],
[ 0., 0.]])
要从列表rays
中获取相应的值,您需要列表推导(或其他循环):
In [765]: [r[:,-1] for r in rays]
Out[765]: [array([ 2., 1.]), array([ 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'所有光线的coor
In [869]: allrays[:,-1]
Out[869]: array([ 2., 1., 0., 0.])
一个光线子集(因为它是一个切片,它是一个视图)
In [871]: allrays[0:2,:]
Out[871]:
array([[ 0., 1., 2.],
[ 1., 1., 1.]])
另一个子集:
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.]])]
如果这些组是连续的,您可以使用split
:
In [884]: np.split(allrays,[3])
Out[884]:
[array([[ 0., 1., 2.],
[ 1., 1., 1.],
[ 0., 0., 0.]]), array([[ 2., 1., 0.]])]
子数组是视图(使用.__array_interface__
属性进行检查。
实际上,它确实只是将乱七八糟的列表问题提升了一个级别。不过,还有更多的灵活性。您可以构建其他索引子列表,例如
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]
您可以将一些新值连接到allrays
。然后,您可能必须重建索引列表。但我怀疑这种建筑是一次完成的,而重复访问。
我们想到了一个关于从img
(和plt.pcolormesh
)产生的plt.pcolor
访问值的早期SO问题。一个将图像保持为2d网格上的表面,另一个更通用,仅仅是四边形的集合,每个都具有定义其边界的颜色和路径。
答案 1 :(得分:1)
在回答您的具体问题时,通常[ray1[-1],ray2[-1],ray3[-1],ray4[-1]]
包含四个“光线”列表的最后一个元素的列表。
由于您的主要关注点似乎是执行速度,我假设您必须一遍又一遍地执行此操作。您是否考虑过创建一个代表最后一个元素的小数据结构,例如last_element = [r1x,r2x,r3x,r4x]
并在您逐步解决问题时保持其值?每次更改last_element
时,都会根据需要将新数据附加到其他列表。换句话说,不是从大列表中重复提取最后一个元素,而是从最后一个元素开始逐步构建大列表。只要你必须构建那些大型列表,那就必须更有效率。它能解决你的问题吗?