是否有作用于现有数组的“np.repeat”?
Is there an `np.repeat` which acts on an existing array?
我有一个很大的 NumPy 数组,我想在循环的每次迭代中用新数据填充它。数组填充沿轴 0 重复的数据,例如:
[[1, 5],
[1, 5],
[1, 5],
[1, 5]]
我知道如何在每次迭代中从头开始创建这个数组:
x = np.repeat([[1, 5]], 4, axis=0)
但是,我不想每次都创建一个新数组,因为它是一个非常大的数组(比 4x2 大得多)。相反,我想使用上面的代码提前创建数组,然后在每次迭代时用新数据填充数组。
但是np.repeat()
returns一个新的数组,而不是作用于一个已有的数组。是否有等效于 np.repeat()
的填充现有数组?
正如我们在评论中指出的那样,您可以使用广播分配来用适当大小的一维数组填充您的二维数组:
x[...] = [1, 5]
如果你的大数组在每一行中总是包含相同的项目(即你以后不会更改这些预设值),你几乎可以肯定地在你的代码的后面部分使用广播并且只使用一个初始x
如
x = np.array([[1, 5]])
此数组的形状为 (1, 2)
,与上例中其他形状为 (4, 2)
的数组广播兼容。
如果您总是需要在每一行中使用相同的值 和 由于某种原因您不能使用广播(这两种情况都不太可能),您可以使用 broadcast_to
在不复制内存的情况下创建具有显式二维形状的数组:
x_bc = np.broadcast_to([1, 5], (4, 2)) # broadcast 1d [1, 5] to shape (4, 2)
这可能有效,因为它具有正确的形状,内存中只有 2 个唯一元素:
>>> x_bc
array([[1, 5],
[1, 5],
[1, 5],
[1, 5]])
>>> x_bc.strides
(0, 8)
但是你不能改变它,因为它是一个只读视图:
>>> x_bc[0, :] = [2, 4]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-35-ae12ecfe3c5e> in <module>
----> 1 x_bc[0, :] = [2, 4]
ValueError: assignment destination is read-only
所以,如果你只需要在每一行中使用相同的值 and 你就不能使用广播 and 你想改变那些稍后相同的行,您可以使用 stride tricks 将相同的一维数据映射到二维数组:
>>> x_in = np.array([1, 5])
... x_strided = np.lib.stride_tricks.as_strided(x_in, shape=(4,) + x_in.shape,
... strides=(0,) + x_in.strides[-1:])
>>> x_strided
array([[1, 5],
[1, 5],
[1, 5],
[1, 5]])
>>> x_strided[0, :] = [2, 4]
>>> x_strided
array([[2, 4],
[2, 4],
[2, 4],
[2, 4]])
它给你一个固定形状的二维数组,它总是包含一个唯一的行,改变任何行也会改变其余的行(因为基础数据只对应一行)。小心处理,因为如果你想拥有两行不同的行,你将不得不做其他事情。
我有一个很大的 NumPy 数组,我想在循环的每次迭代中用新数据填充它。数组填充沿轴 0 重复的数据,例如:
[[1, 5],
[1, 5],
[1, 5],
[1, 5]]
我知道如何在每次迭代中从头开始创建这个数组:
x = np.repeat([[1, 5]], 4, axis=0)
但是,我不想每次都创建一个新数组,因为它是一个非常大的数组(比 4x2 大得多)。相反,我想使用上面的代码提前创建数组,然后在每次迭代时用新数据填充数组。
但是np.repeat()
returns一个新的数组,而不是作用于一个已有的数组。是否有等效于 np.repeat()
的填充现有数组?
正如我们在评论中指出的那样,您可以使用广播分配来用适当大小的一维数组填充您的二维数组:
x[...] = [1, 5]
如果你的大数组在每一行中总是包含相同的项目(即你以后不会更改这些预设值),你几乎可以肯定地在你的代码的后面部分使用广播并且只使用一个初始x
如
x = np.array([[1, 5]])
此数组的形状为 (1, 2)
,与上例中其他形状为 (4, 2)
的数组广播兼容。
如果您总是需要在每一行中使用相同的值 和 由于某种原因您不能使用广播(这两种情况都不太可能),您可以使用 broadcast_to
在不复制内存的情况下创建具有显式二维形状的数组:
x_bc = np.broadcast_to([1, 5], (4, 2)) # broadcast 1d [1, 5] to shape (4, 2)
这可能有效,因为它具有正确的形状,内存中只有 2 个唯一元素:
>>> x_bc
array([[1, 5],
[1, 5],
[1, 5],
[1, 5]])
>>> x_bc.strides
(0, 8)
但是你不能改变它,因为它是一个只读视图:
>>> x_bc[0, :] = [2, 4]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-35-ae12ecfe3c5e> in <module>
----> 1 x_bc[0, :] = [2, 4]
ValueError: assignment destination is read-only
所以,如果你只需要在每一行中使用相同的值 and 你就不能使用广播 and 你想改变那些稍后相同的行,您可以使用 stride tricks 将相同的一维数据映射到二维数组:
>>> x_in = np.array([1, 5])
... x_strided = np.lib.stride_tricks.as_strided(x_in, shape=(4,) + x_in.shape,
... strides=(0,) + x_in.strides[-1:])
>>> x_strided
array([[1, 5],
[1, 5],
[1, 5],
[1, 5]])
>>> x_strided[0, :] = [2, 4]
>>> x_strided
array([[2, 4],
[2, 4],
[2, 4],
[2, 4]])
它给你一个固定形状的二维数组,它总是包含一个唯一的行,改变任何行也会改变其余的行(因为基础数据只对应一行)。小心处理,因为如果你想拥有两行不同的行,你将不得不做其他事情。