JDS*_*JDS 6 python arrays numpy
我有:
test = np.random.randn(40,40,3)
Run Code Online (Sandbox Code Playgroud)
我想做:
result = Repeat(test, 10)
Run Code Online (Sandbox Code Playgroud)
这样result
包含test
重复10次的数组,形状如下:
(10, 40, 40, 3)
Run Code Online (Sandbox Code Playgroud)
因此,使用新轴创建一个张量,以容纳10个副本test
.我也想尽可能高效地做到这一点.我怎么能和Numpy一起做这个?
谢谢!
Odd*_*org 10
您可以使用以下np.repeat
方法np.newaxis
:
import numpy as np
test = np.random.randn(40,40,3)
result = np.repeat(test[np.newaxis,...], 10, axis=0)
print(result.shape)
>> (10, 40, 40, 3)
Run Code Online (Sandbox Code Playgroud)
假设您要复制值 10 次,则只能复制 10stack
个数组:
def repeat(arr, count):
return np.stack([arr for _ in range(count)], axis=0)
Run Code Online (Sandbox Code Playgroud)
axis=0
实际上是默认值,所以在这里并不是真的有必要,但我认为它更清楚地表明您在前面添加了新轴。
事实上,这与示例stack
所做的几乎相同:
>>> arrays = [np.random.randn(3, 4) for _ in range(10)]
>>> np.stack(arrays, axis=0).shape
(10, 3, 4)
Run Code Online (Sandbox Code Playgroud)
但是repeat
是关于在现有轴上重复(或展平阵列),因此您需要reshape
在之前或之后。(这同样有效,但我认为并不那么简单。)
并且tile
(假设你使用一个类似数组的reps
——reps
它基本上repeat
是标量)是关于在所有方向上填写一个多维规范,这比你想要的这个简单案例复杂得多。
所有这些选项都将同样有效。它们都将数据复制 10 次以上,这是昂贵的部分;任何内部处理、构建微小的中间对象等的成本都是无关紧要的。使其更快的唯一方法是避免复制。您可能不想这样做。
但是,如果您这样做……要在 10 个副本之间共享行存储,您可能需要broadcast_to
:
def repeat(arr, count):
return np.broadcast_to(arr, (count,)+arr.shape)
Run Code Online (Sandbox Code Playgroud)
请注意,broadcast_to
这实际上并不能保证它避免复制,只是它返回某种只读视图,其中“广播数组的多个元素可能引用单个内存位置”。在实践中,它将避免复制。如果你出于某种原因确实需要保证这一点(或者如果你想要一个可写的视图——这通常是一个糟糕的主意,但也许你有一个很好的理由......),你必须下降到as_strided
:
def repeat(arr, count):
shape = (count,) + arr.shape
strides = (0,) + arr.strides
return np.lib.stride_tricks.as_strided(
arr, shape=shape, strides=strides, writeable=False)
Run Code Online (Sandbox Code Playgroud)
请注意,一半的文档as_strided
警告你可能不应该使用它,另一半警告你绝对不应该将它用于可写视图,所以......在做之前确保这是你想要的。