Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从第一维度进行numpy广播_Python_Numpy - Fatal编程技术网

Python 从第一维度进行numpy广播

Python 从第一维度进行numpy广播,python,numpy,Python,Numpy,在NumPy中,是否有一种简单的方法可以广播两个维度数组,例如(x,y)和(x,y,z)?NumPy广播通常与最后一个维度的维度相匹配,因此通常的广播将不起作用(它将要求第一个数组具有维度(y,z)) 背景:我正在处理图像,其中一些是RGB(形状(h,w,3)),一些是灰度(形状(h,w))。我生成形状为(h,w)的alpha遮罩,并希望通过遮罩*im将遮罩应用于图像。因为上面提到的问题,这不起作用,所以我最后不得不做 mask = mask.reshape(mask.shape + (1,)

在NumPy中,是否有一种简单的方法可以广播两个维度数组,例如
(x,y)
(x,y,z)
?NumPy广播通常与最后一个维度的维度相匹配,因此通常的广播将不起作用(它将要求第一个数组具有维度
(y,z)

背景:我正在处理图像,其中一些是RGB(形状
(h,w,3)
),一些是灰度(形状
(h,w)
)。我生成形状为
(h,w)
的alpha遮罩,并希望通过
遮罩*im
将遮罩应用于图像。因为上面提到的问题,这不起作用,所以我最后不得不做

mask = mask.reshape(mask.shape + (1,) * (len(im.shape) - len(mask.shape)))

这很难看。代码的其他部分对向量和矩阵进行操作,这也遇到了同样的问题:它无法执行
m+v
,其中
m
具有形状
(x,y)
,而
v
具有形状
(x,)
。例如,可以使用
至少\u 3d
,但我必须记住我实际需要的尺寸。

使用np索引。newaxis在该位置创建一个新轴。即

xyz = #some 3d array
xy = #some 2d array
xyz_sum = xyz + xy[:,:,np.newaxis]
or
xyz_sum = xyz + xy[:,:,None]

以这种方式索引将在该位置创建一个具有形状1和步幅0的轴。

作为另一个角度:如果您经常遇到此模式,则创建一个实用程序函数以强制右广播可能会很有用:

def right_broadcasting(arr, target):
    return arr.reshape(arr.shape + (1,) * (target.ndim - arr.ndim))

虽然只有两种类型的输入(已经有3个DIM或只有2个DIM),但我认为最好使用单个if语句。

使用转置如何:

(a.T + c.T).T

为什么不干脆装修一下呢

def flipflop(func):
    def wrapper(a, mask):
        if len(a.shape) == 3:
            mask = mask[..., None]
        b = func(a, mask)
        return np.squeeze(b)
    return wrapper

@flipflop
def f(x, mask):
    return x * mask
然后


numpy
函数通常都有代码块,用于检查尺寸、将数组重塑为兼容的形状,所有这些都是在开始进行加法或乘法的核心业务之前完成的。它们可以改变输出的形状以匹配输入。所以,滚动你自己做的类似操作没有什么错

不要轻易放弃将变量
3
维度旋转到维度起点的想法。这样做可以利用
numpy
在开始时自动添加维度这一事实

对于逐元素乘法,
einsum
功能非常强大

np.einsum('ij...,ij...->ij...',im,mask)
将处理
im
mask
是2维或3维的任意组合的情况(假设前2维始终兼容。不幸的是,这不能推广到加法或其他操作


不久前,我用纯Python版本模拟了
einsum
。为此,我使用了
np.lib.stride\u技巧。as\u stride
np.nditer
。如果您想在混合和匹配维度方面获得更大的能力,请查看这些函数。

很简单,您只需在较小数组的末尾添加一个单体维度。例如,如果xyz_数组有形状(x,y,z),xy_数组有形状(x,y),你可以这样做

xyz_array + np.expand_dims(xy_array, xy_array.ndim)

是的,但我仍然需要确定目标是有2个轴还是3个轴。(实际上,我一开始就尝试了这一点,但在灰度图像上失败了,分配了1024*1024*1024大小的数组,并耗尽了我的内存)在这种情况下,我会在相关代码前面放一行,将维数太低的数组“向上广播”到正确的广播模式;例如,如果arr.ndim==3,则arr=arr,否则arr[…,无]。这仍然是一行额外的代码,但我不认为您可以避免,至少它比基于重塑的解决方案更具可读性。在立即拒绝此方法之前,您应该尝试理解它生成
1024*1024*1024
。我猜它是在尝试执行
yz[None,:,:]+xy[:,:,None]
其中维度为
1024
。我觉得有点神秘。这个答案不清楚。问题中没有出现符号
A
c
。这需要更多解释。
xyz_array + np.expand_dims(xy_array, xy_array.ndim)