我有一个简单的问题。我看过的许多教程都展示了除了这种常见情况以外的所有内容。我想逐个元素地进行向量-向量相乘,其中向量之一是矩阵的切片。
我无法与外壳交互地重复此问题,因此我不理解。以下只是说明问题的代码部分。
Ordr = 2 # these values set higher up in the code
nx = 5
dx = np.empty((Ordr-1,nx),dtype=float)
# vector dpx and dx calculated in other code here
print('shapes dpx,dx',dpx.shape,dx.shape)
ap.arrayprint('root calc:',dpx,np.transpose(dx)) # not shown originally
dtmp = dpx*dx[0,:]
print('shape dtmp',dtmp.shape)
results are:
shapes dpx,dx (5,) (1, 5)
shape dtmp (5,5)
我希望dtmp形状良好(5,) 尽管我尚未检查实际数字,但似乎正在计算外部乘积。如果我颠倒顺序也没有什么区别,即dpx [0,:] * dx 就像我说的那样,我无法在shell中复制问题,所以我想知道会产生什么。我在Cygwin上运行版本3.6.8。在Windows版本3.7.3rc1下也会发生相同的结果。
2019年7月18日发布的新帖子
进一步检查发现,调用函数进行表格打印导致了此问题。该函数将矢量与二维数组一起打印为列。这可以通过以下方式重塑向量来实现:
a.shape = (n,1)
函数调用之后,此重塑将传递回调用例程。由于dp为(5,1),因此乘以(5,)向量就是(5,1)矩阵。调用广播会导致(5,5)结果。
我是一名新的python程序员,我(错误地)认为对输入的此修改不会传递回调用方。以这种方式修改功能输入是否出错?是否应该在功能中将其标记为错误?我了解C按值传递和Fortran按引用传递,但不了解Python如何将参数传递给函数。有人可以指出我对Python调用约定的解释吗?
基于此发现,帖子标题完全错误。我现在的问题是-为什么Python允许我更改函数的输入?值得以其他标题发布吗?
答案 0 :(得分:0)
尝试重新创建示例:
In [104]: dpx=np.arange(5); dpx.shape
Out[104]: (5,)
In [105]: dx = np.zeros((1,5)); dx.shape
Out[105]: (1, 5)
In [106]: dpx*dx[0,:]
Out[106]: array([0., 0., 0., 0., 0.])
In [107]: _.shape
Out[107]: (5,)
关于您的新信息。
a.shape = (n,1)
此操作会更改a
本身的形状,其中np.reshape(a, (n,1))
或a.reshape(n1,1)
会创建一个具有新形状的新数组(但通常是view
共享数据缓冲区)。
传递给函数时:
def foo(a, b):
a.shape = (n,1)
b = b.reshape(n,1)
foo(A,B)
A
和B
均通过引用传递给foo
。也就是说,外部命名空间中A
引用的对象由内部命名空间中的a
引用。 a.shape
就地更改该对象,然后此更改出现在A
所引用的同一对象中。
但是B
不变。 b
获得新的对象分配,并成为local
。 B
和b
之间的链接已断开。
通常,Python不会自动复制对象,至少不会简单地将它们传递给函数(并返回)。您必须自己制作它们,或使用创建新对象的功能。
我不确定术语是否正确,但是这个答案符合我的理解: