【问题标题】:Stacking arrays with one different dimension using numpy使用 numpy 堆叠具有一个不同维度的数组
【发布时间】:2021-12-29 15:49:34
【问题描述】:

假设我有 2 个数组:

a = np.array([[[1],[1]],[[2],[2]],[[3],[3]],[[4],[4]]])
b = np.array(["a", "b", "c", "d"]).reshape(4,1,1)

然后是a.shape = (4,2,1)b.shape=(4,1,1)。我想要的输出应该是这样的

c = np.array([
[
    np.array([[1],[1]]), "a"
],
[
    np.array([[2],[2]]), "b"
],
[
    np.array([[3],[3]]), "c"
],
[
    np.array([[4],[4]]), "d"
],
])

我尝试了np.hstacknp.concatenate,但这并不完全符合我的要求。我意识到我可以简单地循环遍历 ab 并创建数组,我只是想知道是否有一个特定的函数会返回数组 c 或者循环是我最好的选择。

【问题讨论】:

  • 我看到的最接近的结果是在轴 1 上使用连接,但这不完全是您的预期结果...请问您为什么需要这个?也许还有其他格式可以满足您的要求..
  • 为什么要在(object dtype)数组中混合数组和字符串?你认为你会从使用数组中获得一些神奇的速度优势吗?还是这样的数组在计算上比列表更好?

标签: python arrays python-3.x numpy


【解决方案1】:

您可以结合使用 zip 和 one-liner 进行迭代

a = np.array([[[1],[1]],[[2],[2]],[[3],[3]],[[4],[4]]])
b = np.array(["a", "b", "c", "d"])
c = np.array([[aa,bb] for aa,bb in zip(a,b)])

【讨论】:

  • 这与 OP 使用 for 循环遍历其数组有何不同?我认为他们正在寻找一个特定的 numpy 函数来进行迭代,因为它将被矢量化或至少用 C 编写。
  • @LiquidSnake,OP 可能不明白他想要什么。 c 是一个对象 dtype 数组,因此“矢量化”魔法不适用。
【解决方案2】:

我能得到的最接近的是使用np.column_stack([a, b])。但是,这将包含 numpy 数组中的字符串字符,而不是像您所拥有的那样。

>>> np.column_stack([a,b])
array([[['1'],
        ['1'],
        ['a']],

       [['2'],
        ['2'],
        ['b']],

       [['3'],
        ['3'],
        ['c']],

       [['4'],
        ['4'],
        ['d']]], dtype='<U11')

【讨论】:

    【解决方案3】:

    首先删除b中不必要的维度:

    In [203]: b1 = b.ravel()
    

    第二次从a创建一个4元素对象dtype数组:

    In [204]: a1 = np.empty(4, object)
    In [205]: a1[:] = list(a)
    In [206]: a1
    Out[206]: 
    array([array([[1],
                  [1]]), array([[2],
                                [2]]), array([[3],
                                              [3]]), array([[4],
                                                            [4]])],
          dtype=object)
    

    现在我们可以stack他们在新的第二个轴上创建一个 (4,2) 数组:

    In [207]: np.stack((a1,b1), axis=1)
    Out[207]: 
    array([[array([[1],
                   [1]]), 'a'],
           [array([[2],
                   [2]]), 'b'],
           [array([[3],
                   [3]]), 'c'],
           [array([[4],
                   [4]]), 'd']], dtype=object)
    

    列表推导更简单,而且可能更快:

    In [209]: [[i,j.item()] for i,j in zip(a,b)]
    Out[209]: 
    [[array([[1],
             [1]]),
      'a'],
     [array([[2],
             [2]]),
      'b'],
     [array([[3],
             [3]]),
      'c'],
     [array([[4],
             [4]]),
      'd']]
    

    或者制作一个包含 2 个字段的结构化数组:

    In [215]: c = np.zeros(4, dtype='O,U1')
    In [216]: c
    Out[216]: 
    array([(0, ''), (0, ''), (0, ''), (0, '')],
          dtype=[('f0', 'O'), ('f1', '<U1')])
    In [218]: c['f0'] = list(a)
    In [219]: c['f1'] = b.ravel()
    In [220]: c
    Out[220]: 
    array([(array([[1],
                  [1]]), 'a'), (array([[2],
                                      [2]]), 'b'), (array([[3],
                                                          [3]]), 'c'),
           (array([[4],
                  [4]]), 'd')], dtype=[('f0', 'O'), ('f1', '<U1')])
    

    In [221]: c = np.zeros(4, dtype=[('a',int,(2,1)),('b','U1')])
    In [222]: c['a']=a    
    In [224]: c['b']=b.ravel()
    In [225]: c
    Out[225]: 
    array([([[1], [1]], 'a'), ([[2], [2]], 'b'), ([[3], [3]], 'c'),
           ([[4], [4]], 'd')], dtype=[('a', '<i8', (2, 1)), ('b', '<U1')])
    

    所有这些方法的关键是了解您要创建的内容。您不是在制作“普通”多维数组。您正在尝试混合使用数组和字符串。

    您可以concatenate 制作 (4,3,1) - 并通过指定 dtype 来保留整数。这将 (4,2,1) 与中间维度上的 (4,1,1) 连接起来。这就是连接(以及stack 派生类)最擅长的。

    In [263]: np.concatenate((a,b),axis=1, dtype=object)
    Out[263]: 
    array([[[1],
            [1],
            ['a']],
    
           [[2],
            [2],
            ['b']],
    
           [[3],
            [3],
            ['c']],
    
           [[4],
            [4],
            ['d']]], dtype=object)
    

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 2018-06-16
      • 1970-01-01
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      相关资源
      最近更新 更多