在python中,将数组或列表数组连接起来,输出相同的数据类型。

问题描述 投票:0回答:1

考虑以下数组

import numpy as np
a1 = np.array([1,2,3],dtype='object')
a2 = np.array([["A"],["D"],["R"]],,dtype='object')
a3 = np.array([["A","F"],["D"],["R"]],dtype='object')

下面两个给出了不同类型的输出。没想到会这样。这是正常的吗?

np.c_[a1,a2]

#array([[1, 'A'],
#      [2, 'D'],
#      [3, 'R']], dtype=object)

np.c_[a1,a3]

#array([[1, list(['A', 'F'])],
#      [2, list(['D'])],
#      [3, list(['R'])]], dtype=object)

为什么第一种表达式能用,第二种表达式不能用?我没有看到任何不同的 a2a3. 此外,哪种连接方法(c_, stack, concatenation)可以输出相同类型的输出,而不需要添加其他代码行,如检查输出数据类型并根据需要进行转换。

np.concatenate((a1,a2),axis=0) # Error: ValueError: all the input arrays must have same number of dimensions

np.concatenate((a1,a3),axis=0) # works
#array([1, 2, 3, list(['A', 'F']), list(['D']), list(['R'])], dtype=object)
python numpy concatenation
1个回答
1
投票

这其实是有道理的,看看每个数组的类型。

a1 = np.array([1,2,3],dtype='object') => 1D array of objects, size 3
a2 = np.array([["A"],["D"],["R"]],,dtype='object') => 2D array of objects, size 3x1
a3 = np.array([["A","F"],["D"],["R"]],dtype='object') => 1D array of lists of objects

a3 是一个列表数组,因为np 2d(或更多-d)数组是矩阵,你不可能有1行大小为1,第二行大小为3,np的计算效率很大程度上是由于数组在内存中的组织方式。

所以numpy的解释是 np.array([["A","F"],["D"],["R"]],dtype='object') 作为一个列表数组(也是对象).如果用不同的类型尝试这样做,将导致错误。

np.array([[1,2],[3],[4]],dtype=np.int64) -->
ValueError: setting an array element with a sequence.

因此 np.concatenate((a1,a2),axis=0) 失败,因为a1的形状是 (3,) 而a2的形状是 (3,1),而a1和a3都是 (3,).

你可以用以下方法解决。

np.concatenate((a1,np.reshape(a2,a1.shape)))
np.concatenate((np.reshape(a1,a2.shape),a2))

两种方法都是有效的, 每一种方法都有不同的结果, 没有一种方法可以解决, 因为这两种方法之间的连号 a1a2 是模棱两可的。


1
投票

numpy doc: 特别是,数组在升级到至少2-D之后,将沿其最后一个轴堆叠,并将1的后缀到形状上(由1-D数组组成的列向量)。 这意味着 np.c_ 将首先把一维数组转换为二维数组,然后沿第二轴进行连接。下面是发生的事情。

如果是 np.c_[a1,a2]:

  1. 转换 a1[[1],[2],[3]]
  2. 一堆 [[1],[2],[3]][["A"],["D"],["R"]] 沿第二轴的结果是:

    [[1 'A']
     [2 'D']
     [3 'R']]
    

如果是 np.c_[a1,a3]:

  1. 转换 a1[[1],[2],[3]]
  2. 试图堆叠 [[1],[2],[3]][["A","F"],["D"],["R"]] 沿着第二轴。然而,numpy数组必须是矩形的,并且 a3 不是。另一种方法是将每个列表解释为单项,并像下面一样堆叠成矩形(3,2)。

    [[1 list(['A', 'F'])]
     [2 list(['D'])]
     [3 list(['R'])]]
    

根据你对输出的要求,有不同的方法。如果你想简单地将一个1D2D数组的混合数组串联成1D,你可以先用 squeeze (删除尺寸为1的维度),然后像这样连接。

np.concatenate((np.squeeze(a1),np.squeeze(a2)),axis=0)
#[1 2 3 'A' 'D' 'R']
np.concatenate((np.squeeze(a1),np.squeeze(a3)),axis=0)
#[1 2 3 list(['A', 'F']) list(['D']) list(['R'])]

你也可以 hstack 来连接所有内部列表的内容。

np.concatenate((np.hstack(a1),np.hstack(a2)),axis=0)
#[1 2 3 'A' 'D' 'R']
np.concatenate((np.hstack(a1),np.hstack(a3)),axis=0)
#['1' '2' '3' 'A' 'F' 'D' 'R']
© www.soinside.com 2019 - 2024. All rights reserved.