【问题标题】:NumPy Insert Function: what are the effects of using a single integer index vs a list of indices? How is shape affected?NumPy 插入函数:使用单个整数索引与索引列表有什么影响?形状如何受到影响?
【发布时间】:2021-02-22 14:07:43
【问题描述】:

我研究 NumPy 已经有一段时间了,一个奇怪的行为阻止了我。

我希望以下代码 sn-ps 可以帮助:

这是我将使用的数组:
e = np.arange(1, 10).reshape((3,3))

1- 将值插入排名 1 的数组:
np.insert(e, 0, [1,2,3])np.insert(e, [0], [1,2,3]) 是等价的。
输出: array([1, 2, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9])

2- 将值插入 2 级数组(行):
np.insert(e, 0, [10,11,12], axis=0)np.insert(e, [0], [10,11,12], axis=0) 是等效的。
请注意,我没有使用行的形状 -[[10,11,12]]- 并且效果很好。

尽管如此,我尝试了np.insert(e, 0, [[10,11,12]], axis=0)np.insert(e, [0], [[10,11,12]], axis=0) 并获得了相同的结果。

output:
array([[10, 11, 12],
       [ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9]]) 

正如预期的那样,使用np.insert(e, [0,2], [10,11,12], axis=0)np.insert(e, [0,2], [[10,11,12]], axis=0) 会将行插入到数组中的两个不同位置。

output:
array([[10, 11, 12],
       [ 1,  2,  3],
       [ 4,  5,  6],
       [10, 11, 12],
       [ 7,  8,  9]])

现在是奇怪的行为。

3- 将值插入 2 级数组(列):
一个。 (1)np.insert(e, 0, [10,11,12], axis=1) VS (2)np.insert(e, [0], [10,11,12], axis=1).
湾。 (3)np.insert(e, 0, [[10],[11],[12]], axis=1) 与 (4)np.insert(e, [0], [[10],[11],[12]], axis=1).

a. outputs from (1) and (4):
array([[10,  1,  2,  3],
       [11,  4,  5,  6],
       [12,  7,  8,  9]]) 
b. outputs from (2) and (3):
array([[10, 11, 12,  1,  2,  3],
       [10, 11, 12,  4,  5,  6],
       [10, 11, 12,  7,  8,  9]])

c。 (5)np.insert(e, [0,2], [[10],[11],[12]], axis=1) VS (6)np.insert(e, [0,2], [10,11,12], axis=1).

output from (5):
array([[10,  1,  2, 10,  3],
       [11,  4,  5, 11,  6],
       [12,  7,  8, 12,  9]])
The output from (6):
ValueError: shape mismatch: value array of shape (3,) could not be broadcast to indexing result of shape (2,3)

1- 如果形状是可选的,如行示例,为什么代码 (1) 和 (4) 中的列不是这种情况?

2- 如果形状很重要,为什么它适用于 (4) 而不是 (3)?

3- 如果形状是强制性的,那么(5)和(6)有什么区别?为什么 NumPy 会在 (6) 中广播这个元素列表?

【问题讨论】:

  • np.insert 是一个复杂的 python 函数,根据输入采取不同的方法。稍后 ut 会连接一些数组,或者创建一个接收数组并将数组复制到它。你也可以这样做,而且可能更快。
  • 我依稀记得回答过一个类似的问题(在过去的一年或 2 年)。 object(尤其是标量还是列表)和 values 形状之间的相互作用很难理清。文档试图解释这一点。我不确定我现在想花时间重新审视它。
  • 我认为在所有这些情况下insert 都会根据objectvalues 的大小(和类型)计算返回结果。它将原件复制到适当的空间,然后复制值。使用 2 个插入“列”和 3 个(或 (3,1))值,它可以将输出形状扩展 2 或 6 (2 x 3)。

标签: python numpy numpy-ndarray array-broadcasting


【解决方案1】:

文档说:

`values` should be shaped so that ``arr[...,obj,...] = values``
is legal.

这是一个例子:

将 2 行插入 (3,3) 数组:

In [19]: e=np.zeros((3,3),int)
In [32]: res=np.insert(e,[0,2],[1,2,3],axis=0)
In [33]: res
Out[33]: 
array([[1, 2, 3],
       [0, 0, 0],
       [0, 0, 0],
       [1, 2, 3],
       [0, 0, 0]])

结果是一个 (5,3) 数组。可以通过以下方式访问插入的值:

In [34]: res[[0,3],:]
Out[34]: 
array([[1, 2, 3],
       [1, 2, 3]])

这是一个 (2,3) 数组。

(我不得不将 (0,2) 更改为 (0,3) 以考虑插入的行。insert 进行了这种调整。

我可以将 (3,) 分配给 (2,3) 插槽。通过广播扩展到 (1,3) 和 (2,3):

In [35]: res[[0,3],:] = [1,2,3]

但是a(3,1)不能广播:

In [36]: res[[0,3],:] = [[1],[2],[3]]
Traceback (most recent call last):
  File "<ipython-input-36-de940597bcbf>", line 1, in <module>
    res[[0,3],:] = [[1],[2],[3]]
ValueError: shape mismatch: value array of shape (3,1)  could not be broadcast to indexing result of shape (2,3)

您的 (6) 也有同样的问题,但有列:

In [38]: res=np.insert(e,[0,2],3,axis=1)
In [39]: res
Out[39]: 
array([[3, 0, 0, 3, 0],
       [3, 0, 0, 3, 0],
       [3, 0, 0, 3, 0]])
In [40]: res[:,[0,3]]            # a (3,2) insert
Out[40]: 
array([[3, 3],
       [3, 3],
       [3, 3]])
In [41]: res[:,[0,3]] = np.ones((3,2))
In [42]: res[:,[0,3]] = np.ones((3,1))  # broadcasts fine

但是 (3,) 和 (1,3) 不能放在 (3,2) 空格中:

In [43]: res[:,[0,3]] = np.ones((3,))
Traceback (most recent call last):
  File "<ipython-input-43-3a546b2939fc>", line 1, in <module>
    res[:,[0,3]] = np.ones((3,))
ValueError: shape mismatch: value array of shape (3,)  could not be broadcast to indexing result of shape (2,3)

In [44]: res[:,[0,3]] = np.ones((1,3))
Traceback (most recent call last):
  File "<ipython-input-44-6858764218b0>", line 1, in <module>
    res[:,[0,3]] = np.ones((1,3))
ValueError: shape mismatch: value array of shape (1,3)  could not be broadcast to indexing result of shape (2,3)

我不明白为什么错误消息显示to indexing result of shape (2,3)。我希望阅读 (3,2)。

作为参考,这里是带有insert 错误的完整回溯:

In [45]: np.insert(e, [0,2], [10,11,12], axis=1)
Traceback (most recent call last):
  File "<ipython-input-45-a7ae562f20c6>", line 1, in <module>
    np.insert(e, [0,2], [10,11,12], axis=1)
  File "<__array_function__ internals>", line 5, in insert
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 4678, in insert
    new[tuple(slobj)] = values
ValueError: shape mismatch: value array of shape (3,)  could not be broadcast to indexing result of shape (2,3)

new 必须是形状为 (3,5) 的数组,tuple(slobj) 类似于 (slice(None), np.array([0,3]))(与我的 [:,[0,3]] 类似),valuesnp.array([10,11,12]) 数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 2017-05-31
    相关资源
    最近更新 更多