【问题标题】:Python: How to split a list into ordered chunksPython:如何将列表拆分为有序块
【发布时间】:2022-01-20 20:35:31
【问题描述】:

如果我有以下列表

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

然后

np.array_split([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)

返回

[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8, 9])]

有没有办法按以下顺序获取子数组?

[array([0, 3, 6, 9]), array([1, 4, 7]), array([2, 5, 8])]

【问题讨论】:

  • 是否需要numpy.ndarray,或者list 是否满足您的要求?
  • 我需要获取子列表(块)的列表

标签: python numpy


【解决方案1】:

由于列表的长度不同,numpy.ndarray 不费吹灰之力是不可能的,因为所有子数组的长度必须相同。

但是,如果一个简单的list 满足您的要求,您可以使用:

l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l2 = []

for i in range(3):
    l2.append(l[i::3])

输出:

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

或者更简洁,给出相同的输出:

[l[i::3] for i in range(3)]

【讨论】:

  • 如果 lnp.array,此解决方案也适用。无需先转换为list。结果是子np.ndarray.views 的list(后来对 l 的更改反映在子视图中)。
【解决方案2】:

让我们看看np.array_split的源代码重构:

def array_split(arr, Nsections):
    Neach_section, extras = divmod(len(arr), Nsections)
    section_sizes = ([0] + extras * [Neach_section + 1] + (Nsections - extras) * [Neach_section])
    div_points = np.array(section_sizes).cumsum()

    sub_arrs = []
    for i in range(Nsections):
        st = div_points[i]
        end = div_points[i + 1]
        sub_arrs.append(arr[st:end])

    return sub_arrs

考虑到您的示例arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]Nsections = 3,它将构造部分大小[0, 4, 3, 3] 和分割点[0, 4, 7, 10]。然后做这样的事情:

[arr[div_points[i]:div_points[i + 1]] for i in range(3)]

确实,试图模仿numpy 的行为

def array_split_withswap(arr, N):
    sub_arrs = []
    for i in range(N):
        sub_arrs.append(arr[i::N])

是最好的选择(就像在@S3DEV 解决方案中一样)。

【讨论】: