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)

为什么第一个有效而不是第二个表达式?a2我看不出和之间有什么区别a3。此外,哪种连接方法(c_、堆栈、连接)将输出相同类型的输出,而无需添加其他代码行,例如检查输出数据类型并根据需要进行转换。

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)
4

2 回答 2

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))

两者都是有效的,每个都有不同的结果,没有 1 个解决方案,因为 和 之间的连接a1a2明确。

于 2020-05-02T08:32:33.937 回答
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'])]]
    

根据您希望输出的方式,有不同的方法。如果您想简单地将 1D/2D 数组的混合连接成 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']
于 2020-05-02T10:09:24.090 回答