4

我在 Python 中使用矩阵(numpy)操作,并遇到了一个有趣的观察结果。

如果我有以下代码:

 x=matrix([[1,2],[3,4]])
 y=matrix([[1.1,2.1],[3.1,4.1]])
 x=y
 print x

然后它打印[[1.1,2.1],[3.1,4.1]]

但是,如果我这样做

 x=matrix([[1,2],[3,4]])
 y=matrix([[1.1,2.1],[3.1,4.1]])
 x[:,:]=y[:,:]
 print x

然后它只打印整数部分,即[[1,2],[3,4]]

有人能告诉我这是什么原因吗?

4

3 回答 3

5

名称xy只是您可以分配给对象的标签。它们不像其他语言那样是真正的“变量”,并且没有为它们分配任何类型。

执行线

x = y

将简单地将标签附加到当前指向x的对象y,并删除对它之前指向的对象的引用(如果这是唯一的引用,可能会导致旧对象被垃圾回收)。执行此行后,x is y返回True,表示它们现在都指向同一个对象。

线

x[:] = y

另一方面,不是简单地将新标签附加到对象上,而是修改现有标签,即 指向的标签x。由于此现有对象具有 item 类型int32,因此所有值都需要转换为整数。执行此行后,x is y返回False,表示它们指向不同的对象。

于 2013-07-24T19:39:45.253 回答
0

您的 x 矩阵的 dtype 为 int32

编辑:一个更有趣的结果是:

>>> x = np.matrix([[1,2],[3,4]],dtype='f')
>>> y = np.matrix([[1.1,2.1],[3.1,4.1]],dtype='f')
>>> x[:,:] = y[:,:]
>>> x
matrix([[ 1.10000002,  2.0999999 ],
        [ 3.0999999 ,  4.0999999 ]], dtype=float32)

但这是由 python 浮动错误引起的。

于 2013-07-24T19:36:52.287 回答
0

在第一种情况下,当您使用赋值时x = y,您将内存位置设置x为的内存位置y,所以现在基本上x只是一个冗余变量,指向内存中指向的相同位置y。这样,看起来您正在创建 matrix 的副本y,但实际上您不是。如果您要y在此分配之后进行操作,然后print xand print y,您会看到它们都发生了变化。

在第二种情况下,因为x被初始化为整数矩阵,所以正在应用一些自动类型转换来强制新分配的每个元素的值x是整数。y当您使用x[:,:] = y[:,:]赋值时,您实际上是在复制矩阵的值,但是因为x是整数矩阵,Python 基本上是在执行x[:,:] = int(y[:,:]).

您可以改为初始化x为:

x = matrix([[1.0, 2.0], [3.0, 4.0]])

或作为:

x = matrix([[1, 2], [3, 4]], dtype='f')

并且您应该在执行后看到您期望的结果x[:,:] = y[:,:]

于 2013-07-24T19:41:06.977 回答