完全陷入了一个相当愚蠢的问题:我试图计算对象之间某些属性的点积,但不断得到一个值错误-形状不匹配-但形状相同(2,1)和(2,1),因为数组只是同一类的不同实例的属性:
class MyClass(Object):
def __init__(self, a,b, x,y):
self.prop_1 = np.array((a,b))
self.prop_2 = np.array((x,y))
其中a、b、x和y都是标量。然后再往下走,我正在努力
def MyFunction(Obj1, Obj2):
results = np.dot(Obj1.prop_1 - Obj2.prop_1, Obj2.prop_2 - Obj2.prop_3)
它不断抛出值错误
ValueError: shapes (2,1) and (2,1) not aligned: 1 (dim 1) != 2 (dim 0)
从数学上讲,这个点积应该很好——但是错误消息的最后一位暗示我必须转置其中一个数组。我非常感谢对numpy形状解释的简短解释,以避免这种错误
编辑:
我想我有点说错了。当我通过(案例a)启动我的对象时
a,b = np.random.rand(2)
x,y = np.random.rand(2)
MyClass(a, b, x, y)
每件事都很有魅力。如果相反,我启动as(案例b)
a = np.random.rand(1)
b = np.random.rand(1)
x = np.random.rand(1)
y = np.random.rand(1)
MyClass(a, b, x, y)
由于形状不匹配,点积后来无法工作
我注意到,在案例b中,每个单独的值都是shape(1,)
,我很清楚,在案例a中,组合这两个值将导致shape(2,1)
,而不是shape()
,但是为什么这两种声明变量的方法会导致不同的形状呢
正如您所知,我对Python比较陌生,并且认为这只是执行多个任务的一种简洁方式——事实证明,这背后有一些进一步的推理,我很想听听这方面的情况
第1部分
问题是数组是完整的二维矩阵,而不是^{} 理解的一维“向量”。要使乘法工作,您需要(a)将向量转换为向量:
(b)设置矩阵乘法,以便维度工作。记住,两个Nx1矩阵的点积是ATB:
或者(c),使用np.einsum显式设置和的维度:
对于使用} (或等效的} ,因为您有二维数组
dot
的所有示例,您可以使用^{@
运算符)或^{通常,在使用
dot
时,请记住以下规则。表单元格是einsum
下标基本上,
dot
沿着最后两个维度遵循矩阵乘法的正常规则,但是前导维度总是组合在一起的。如果希望阵列的前导维度一起广播>;2D(即,将矩阵堆栈中的对应元素相乘,而不是所有可能的组合),使用matmul
或@
第二部分
将输入初始化为
a, b = np.random.rand(2)
时,将数组的两个元素解压为标量:注意,在这种情况下,类型不是
numpy.ndarray
。但是,当您执行a = np.random.rand(1)
时,结果是一个元素的1D数组:从numpy阵列创建numpy阵列时,结果是二维阵列:
展望未来,你有两个选择。您可以更加小心地处理输入,也可以在创建阵列后对其进行清理
可以展开馈入的阵列:
或者,您也可以在创建阵列后展平/展开阵列:
您可以使用
....reshape(-1)
而不是...ravel()
相关问题 更多 >
编程相关推荐