在键入时使用numpy数组数组的奇怪行为

时间:2016-07-27 04:58:21

标签: python numpy

为什么第一个数组完全转换为字符串类型,而第二个数组的各个类型保持不变?如何强制第一个数组(np.array([np.array([1,2,3]), np.array(["a", "bb", "ccc"])]))由dtype = np.int64数组和dtype = np.str_数组组成?我尝试为整个数组设置dtype = object,但这会导致各个数组的dtypes也变为object。

>>> import numpy as np
>>> np.array([np.array([1,2,3]), np.array(["a", "bb", "ccc"])])
array([['1', '2', '3'],
       ['a', 'bb', 'ccc']],
      dtype='<U21')
>>> np.array([np.array([1,2,3, 4]), np.array(["a", "bb", "ccc"])])
array([array([1, 2, 3, 4]), array(['a', 'bb', 'ccc'],
      dtype='<U3')], dtype=object)

3 个答案:

答案 0 :(得分:2)

np.array有时会试图变得过于聪明&#39;但基本原则是它尝试创建可以与输入一起使用的最高维数组。只有当它失败时,才会采用更简单的dtype = object数组。请记住,最初的意图是生成一个多维数字数组。 object dtype是一种较新的,不发达的概括。

使用

np.array([np.array([1,2,3]), np.array(["a", "bb", "ccc"])])

子阵列具有相同的长度。因此,它会创建与列表列表np.array([[1,2,3],["a", "bb", "ccc"]])相同的数组。而且因为它不能强迫&#34; a&#34;要成为一个int,它会强制1成为一个字符串。我不确定为什么它给了你U21和我U11。似乎U3已足够。

另一种想到这一点的方法是在新轴上concatenate。最新版本添加了np.stack,可以更好地控制它。

np.stack([np.array([1,2,3]), np.array(["a", "bb", "ccc"])])

但在第二种情况下,2个阵列的长度不同。它不能从那些数组形成一个二维数组,因此它保持原样,并生成一个1d 2元素的对象数组。

有一些技巧可用于制作具有相等长度元素的对象数组。一个是制作一个正确大小的空对象数组,并分配元素

In [81]: x=np.empty((2,), dtype=object)
In [82]: x[:] = [np.array([1,2,3]), np.array(["a", "bb", "ccc"])]
In [83]: x
Out[83]: 
array([array([1, 2, 3]), array(['a', 'bb', 'ccc'], 
      dtype='<U3')], dtype=object)

另一种方法是从不同大小的元素开始,然后更改或删除一个元素。

In [84]: x = np.array([[1,2,3,4], ["a", "bb", "ccc"]])
In [85]: x[0] = np.array([1,2,3])

答案 1 :(得分:1)

原因是如果子阵列具有兼容的形状,numpy会为其共享形状创建额外的维度。在您的第一个示例中就是这种情况,如果您检查该对象的shape,您会看到它是(2, 3)。在第二个示例中,无法协调子数组形状,因此您获得了形状为(2,)的一维数组。

据我所知,没有办法强制nd.array将数组创建为dtype对象而不将该更改传播到子数组。这是一个有点奇怪的事情,因为numpy数组的大多数好处将被限制或消除。例如,您可以通过预先创建数组并在之后填充它来实现:

x = np.zeros((2,), dtype=object)
x[0] = np.array([1,2,3])
x[1] = np.array(["a", "bb", "ccc"])

>>> x
array([array([1, 2, 3]), array([u'a', u'bb', u'ccc'], 
      dtype='<U3')], dtype=object)
>>> x[0].dtype
dtype('int32')
>>> x[1].dtype
dtype('<U3')

答案 2 :(得分:1)

查看输出:

>>> np.array([np.array([1,2,3]), np.array(["a", "bb", "ccc"])])
array([['1', '2', '3'],
       ['a', 'bb', 'ccc']],
      dtype='<U11')

>>> np.array([np.array([1,2,3,4]), np.array(["a", "bb", "ccc"])])
array([array([1, 2, 3, 4]), array(['a', 'bb', 'ccc'],
      dtype='<U3')], dtype=object)

第一个输出将数组连接成一个2x1数组,每个数组包含三个元素。第二个输出不会连接数组。

现在,请注意:

>>> a = np.array([np.array([1,2,3])])
>>> b = np.array([np.array(['i','j','k'])])
>>> np.concatenate((a, b))
array([['1', '2', '3'],
       ['i', 'j', 'k']],
      dtype='<U11')

>>> a = np.array([np.array([1,2,3,4])])
>>> np.concatenate((a, b))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: all the input array dimensions except for the concatenation axis must match exactly

>>> np.concatenate((a, b), axis=1)
array([['1', '2', '3', '4', 'i', 'j', 'k']],
      dtype='<U11')

看到区别?当Numpy尝试连接整数和整数字符串时,如果它们各自具有相同的维度,NumPy会将整数转换为字符串。如果它们没有相同的尺寸,它就不会连接它们,因为你会得到这些错误。