【问题标题】:Numpy array no longer flattens inputs once upgrading to 1.16升级到 1.16 后,Numpy 数组不再使输入变平
【发布时间】:2021-02-09 06:25:21
【问题描述】:

将代码库从 numpy 1.15.2 升级到 1.16.6 并观察 numpy.array 行为的偏差。 python版本3.6.7。

以前的行为(numpy 1.15.2):

sequence=(1.5, 1.5, 1.5, 1.5, array([5.]))
old_array = numpy.array(sequence)
print(old_array)
array([1.5, 1.5, 1.5, 1.5, 5.0])

新行为(numpy 1.16.6):

sequence=(1.5, 1.5, 1.5, 1.5, array([5.]))
new_array = numpy.array(sequence)
print(new_array)
array([1.5, 1.5, 1.5, 1.5, array([5.])], dtype=object)

在这些示例中,array([5]) 对应于单个元素的 numpy.ndarray。序列是传递给 numpy.array 函数的值元组。在 1.15.2 版本中,numpy.array 基本上将单个元素数组展平,而 1.16.6 将其连接为附加元素。

numpy 1.16.* 的发行说明中没有任何内容似乎暗示数组创建函数的行为发生了变化。如果目标是简单地展平数组 numpy.hstack 可以工作,但是我正在寻找行为变化的解释,因为它可能会对我正在升级的代码库产生其他影响。

【问题讨论】:

  • 早期版本中的dtype 是什么。如果那是准确的复制粘贴,我怀疑只是显示发生了变化,而不是实际的展平。请注意,5 是整数,而不是像其他元素一样浮动。
  • @hpaulj 很抱歉这是一个转录错误。内部数组中的值是一个浮点数,使得序列 = (1.5, 1.5, 1.5, 1.5, array([5.])。似乎改变的是 numpy.array 从将序列视为浮点数变为它们作为对象。
  • 每当我这样做一段时间后,我都会收到此警告,大概是在行为改变之前:<stdin>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  • @juanpa.arrivillaga 可能是相关的。我有兴趣理解的行为是,在某些时候 numpy.array 从将我的示例中的 dtype 推断为 numpy.float64 更改为将其推断为对象。如果我明确地将 dtype=numpy.float64 传递给 numpy.array 调用,则行为与 numpy 1.15 的行为匹配。我主要只是对为什么会发生这种变化感兴趣。

标签: python numpy numpy-ndarray


【解决方案1】:

在我的 cmets 中,我专注于显示的变化,包括一个明确的 array 字。但是我在发行说明中找不到记录。即使没有,您的示例也应该显示为[1.5,1.5,[5.]]

但在当前版本 (1.19) 中:

In [99]: np.array([1.5,1.5,np.array(5)])
Out[99]: array([1.5, 1.5, 5. ])

这里的 0d np.array(5) 是“扁平的”,与浮点数相同。

虽然一维数组会产生参差不齐的警告(从 1.19 开始)和对象 dtype:

In [100]: np.array([1.5,1.5,np.array([5])])
<ipython-input-100-41ccaf61f1ba>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  np.array([1.5,1.5,np.array([5])])
Out[100]: array([1.5, 1.5, array([5])], dtype=object)

如果我将 dtype 显式设置为浮动:

In [101]: np.array([1.5,1.5,np.array([5])],float)
Out[101]: array([1.5, 1.5, 5. ])

因此,在 1.15 中,(1,) 数组可能被视为与 () 形状一相同。

如果我有早期版本,我会检查dtype,并测试np.array([1.5, 1.5, np.array([1,2])]) 之类的表达式。

np.array 是一个复杂的函数。默认行为是创建一个多维数字(或字符串)dtype 数组。如果失败,它会退回到创建一个对象 dtype 数组(现在有一个警告)。但对于某些形状组合,它会引发错误。

In [103]: np.array([np.ones((2,1)), np.ones((2,3))],object)
Traceback (most recent call last):
  File "<ipython-input-103-b2aa52476628>", line 1, in <module>
    np.array([np.ones((2,1)), np.ones((2,3))],object)
ValueError: could not broadcast input array from shape (2,1) into shape (2)

VisibleDeprecationWarning 告诉我们,numpy 开发人员正朝着清理这种np.array 行为的方向前进,消除了经常让新手用户陷入困境的回退行为。

【讨论】:

  • 感谢@hpaulj 的回复!它出现在 numpy 1.15 -> 1.16 之间,如果序列中的任何元素是列表/元组/数组,则更改是推断 dtype=object。这意味着在 numpy 1.15 np.array([1.5, 1.5, np.array([1.5, 1.5]) 将出错,除非 type=object 被传递。而在 1.16 np.array([1.5, 1.5, np.array([ 1.5, 1.5]) 工作正常,推断 dtype=object。我怀疑这个 dtype 推导影响了之前将 (1,) 数组视为浮点数而不是对象的逻辑。然后在 1.19 中添加了警告。仍然希望我可以找到这种处理变化的文档。
猜你喜欢
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
相关资源
最近更新 更多