【问题标题】:How to split a numpy array based on a tuple content? [duplicate]如何根据元组内容拆分 numpy 数组? [复制]
【发布时间】:2019-03-24 15:01:06
【问题描述】:

假设我有一个数组 [0, 1, 2, 3, 4, 5, 6, 7] 和一个元组:(3, 3, 2)

我正在寻找一种方法,根据我的元组数据将我的数组拆分为 3 数组:

[0, 1, 2]
[3, 4, 5]
[6, 7]

我可以编写这样一个简单的代码来获得我想要的东西,但是我正在寻找一种正确的 Pythonic 方式来做到这一点:

为了简单起见,我使用了列表。

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)

pointer = 0
for i in b:
        lst = []
        for j in range(i):
                lst.append(a[pointer])
                pointer += 1
        print(lst)

或者这个:

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)
pointer = 0
for i in b:
        lst = a[pointer:pointer+i]
        pointer += i
        print(lst)

结果:

[0, 1, 2]
[3, 4, 5]
[6, 7]

【问题讨论】:

  • 通常当发帖者询问数组时会很麻烦,但请提供一个列表示例。在这里,它只是一个烦恼。也就是说,np.array_split 的操作与您的第二个解决方案非常相似,使用切片。但它需要一个累积元组。
  • @hpaulj 你是对的......对此感到抱歉。

标签: python numpy


【解决方案1】:

你可以使用numpy的split方法

import numpy as np

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)

c = np.split(a, np.cumsum(b)[:-1])

for r in c:
    print(r)

np.split(a, b) 通过 b 中的索引沿给定轴拆分 a(默认为 0)。

【讨论】:

    【解决方案2】:

    如果您不想修改输入列表,可以使用迭代器和itertools module

    >>> from itertools import islice
    >>> a = [0, 1, 2, 3, 4, 5, 6, 7]
    >>> b = (3, 3, 2)
    >>> i = iter(a)
    >>> [list(islice(i, x)) for x in b]
    [[0, 1, 2], [3, 4, 5], [6, 7]]
    

    在第一步中,您创建一个迭代器,它从a 的第一个元素开始。然后在list comprehension 中迭代b 中的数字,并在每一步中相应地从迭代器中提取许多元素并将它们存储在结果列表中。

    【讨论】:

      【解决方案3】:

      一种更简单的方法是:

      a = [0, 1, 2, 3, 4, 5, 6, 7]
      b = (3, 3, 2)
      
      for ind in b:
          print(a[:ind])
          a = a[ind:]
      

      它循环遍历b 中的切片大小,同时每次都缩短原始数组。如果您需要将结果切片用于其他用途,您可以轻松地将它们附加为子列表。它几乎就像您的解决方案之一,只是它不使用任何额外的变量并直接遍历 b 的元素。

      另外,我不会称变量为ab——当然不是在这种情况下,变量具有明确的含义,可以通过它们的名称来表达。更有意义的名称会减少错误数量并使代码更清晰,与更大/更复杂的代码真正不同。我会打电话给a 至少in_listb slices,但是如果有更多的上下文,这可能会更好。

      【讨论】:

        【解决方案4】:

        最“简洁”的语法是:

        ex_array = [0, 1, 2, 3, 4, 5, 6, 7] extuple = (3, 3, 2)

        result = [ex_array[sum(extuple[:iii]):sum(extuple[:iii])+extuple[iii]] for iii in range(len(extuple))]
        

        result 将是预期子列表的列表

        【讨论】:

          【解决方案5】:

          重用Compare two adjacent elements in same list中的pairwise函数,你还可以:

          from itertools import accumulate
          from more_itertools import pairwise
          
          a = [0, 1, 2, 3, 4, 5, 6, 7]
          b = (3, 3, 2)
          
          [a[slice(*s)] for s in pairwise(accumulate((0,)+b))]
          

          也就是说,np.split 的答案可能更快(并且更容易阅读)。

          【讨论】:

            猜你喜欢
            • 2016-06-06
            • 1970-01-01
            • 2016-07-30
            • 2020-09-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-15
            相关资源
            最近更新 更多