形状不等的 Numpy 堆栈

新手上路,请多包涵

我注意到通过 np.stacknp.dstack 将 2D 数组组合到 3D 数组 的解决方案,或者仅在数组具有相同的 .shape[0] 时传递数组列表才有效 ---

例如,假设我有:

 print(arr)
[[0 1]
 [2 3]
 [4 5]
 [6 7]
 [8 9]]

很容易到达:

 print(np.array([arr[2:4], arr[3:5]])) # same shape
[[[4 5]
  [6 7]]

 [[6 7]
  [8 9]]]

但是,如果我传递一个长度不等的数组列表,我会得到:

 print(np.array([arr[:2], arr[:3]]))
[array([[0, 1],
       [2, 3]])
 array([[0, 1],
       [2, 3],
       [4, 5]])]

我怎样才能简单地:

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

我尝试过的:许多其他 数组操作例程

注意:最终想要对 2 个以上的阵列执行此操作,因此 np.append 可能并不理想。

原文由 Brad Solomon 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 553
2 个回答

Numpy 数组必须是矩形的,因此使用 numpy 数组无法获得您想要获得的内容。

你需要一个不同的数据结构。哪一个合适取决于你想用这些数据做什么。

原文由 Johannes 发布,翻译遵循 CC BY-SA 3.0 许可协议

我已经创建了一个适用于此问题的函数,假设您愿意填充以使形状成为矩形,并且您拥有任意更高的多维数组。它可能可以进一步优化,但还不错。

 import numpy as np
def stack_uneven(arrays, fill_value=0.):
    '''
    Fits arrays into a single numpy array, even if they are
    different sizes. `fill_value` is the default value.

    Args:
            arrays: list of np arrays of various sizes
                (must be same rank, but not necessarily same size)
            fill_value (float, optional):

    Returns:
            np.ndarray
    '''
    sizes = [a.shape for a in arrays]
    max_sizes = np.max(list(zip(*sizes)), -1)
    # The resultant array has stacked on the first dimension
    result = np.full((len(arrays),) + tuple(max_sizes), fill_value)
    for i, a in enumerate(arrays):
      # The shape of this array `a`, turned into slices
      slices = tuple(slice(0,s) for s in sizes[i])
      # Overwrite a block slice of `result` with this array `a`
      result[i][slices] = a
    return result

使用它的唯一警告是输入必须能够被视为一系列 numpy 数组。所以对于你的例子

arr = np.array([[0, 1],
                [2, 3],
                [4, 5],
                [6, 7],
                [8, 9]])
stack_uneven([arr[:2], arr[:3]], 0)

这会给你

array([[[0, 1],
    [2, 3],
    [0, 0]],

   [[0, 1],
    [2, 3],
    [4, 5]]])

但这同样适用于更高维度的事物,例如:

 arr = [np.ones([3, 2, 2]), np.ones([2, 3, 2]), np.ones([2, 2, 3])]

原文由 Multihunter 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题