没有for循环的python numpy数组访问列表

2024-06-16 11:03:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个可变长度数组的列表。 我有这样的东西:

a=[np.array([0, 3, 4]), np.array([1, 8]), np.array([2, 5, 7]), np.array([6])]

并希望从包含多个值的所有数组中提取除第一个值以外的所有值。在for循环中执行它是非常直接的,但是如果不使用for循环来节省时间,我将非常感激。我的for循环是这样的:

^{pr2}$

太多了。在

PS:尽管这是我在这里问的第一个问题,但stackoverflow是我几年前开始攻读博士学位以来的日常科学伙伴。感谢这个神奇的社区。在


Tags: 列表fornp科学数组stackoverflowarray社区
3条回答

您可以使用^{}(删除短字符)和^{}(切片)的组合:

b = map(lambda li: li[1:], filter(lambda li: len(li) > 1, a))

# [array([3, 4]), array([8]), array([5, 7])]

在Python3中,b是一个map对象,它可以像任何其他iterable一样通过list(b)列出。在Python2中,map返回一个list。在

您可以在一行中执行以下操作:

duplicate_pos = [i[1:] for i in a if len(i) != 1]

因为这个列表包含numpy数组,所以我怀疑您希望用numpy操作代替循环,而不仅仅是Python迭代的另一种形式。它可以通过将迭代移动到编译代码来加快速度。对于小阵列来说,由于开销过大,所以速度不快。在

在本例中,您从一个列表开始,而不是一个二维数组,并且该列表包含大小不等的数组。这是一个很好的指示,没有一个纯粹的解决方案。在

更干净的循环版本是(不需要使用索引)

def foo(a):
   b=[]
   for i in a:
       if i.shape[0]>1:   # use len(i) if i might be a list
           b.append(i[1:])
   return b

但这可以很好地表达为列表理解

^{pr2}$

timeit测试中,这比for循环快50%。但是测试用例太小了,我不会在时间差上放太多的股票。在

我希望其他迭代器-生成器、映射、itertools-的时间也差不多。欢迎其他人详细说明时间。在

i[1:]在1(或0)元素数组上运行正常,因此您可能不需要if测试。或者可以在另一个迭代中过滤出空数组。对于小列表,迭代选择通常是样式的问题,what expresses the task most clearly to the reader,而不是时间问题。在


如果子数组的长度相同,或者可能用-1之类的东西填充,那么可以将它们组合成一个2d数组,然后从中进行选择

A = np.vstack(a)
A[:,1:]

但是vstack在列表上迭代,在应用连接之前将每个子数组转换为一个2d数组。仅此一项就比列表解决方案慢。在

相关问题 更多 >