python给矩阵赋值_关于python:numpy数组赋值问题

我在Python2.6.5中有一个关于numpy的奇怪问题。我分配了一个numpy数组,然后将一个新变量等效到它。当我对新数组执行任何操作时,原始数组的值也会更改。为什么会这样?请参阅下面的示例。请启发我,因为我对Python和一般编程还比较陌生。

-苏扬

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21>>> import numpy as np

>>> a = np.array([[1,2],[3,4]])

>>> b = a

>>> b

array([[1, 2],

[3, 4]])

>>> c = a

>>> c

array([[1, 2],

[3, 4]])

>>> c[:,1] = c[:,1] + 5

>>> c

array([[1, 7],

[3, 9]])

>>> b

array([[1, 7],

[3, 9]])

>>> a

array([[1, 7],

[3, 9]])

这实际上根本不是问题,而是数组(和其他对象)在Python中的工作方式。

请这样想:您在代码示例中创建的数组是一个位于内存中某个位置的对象。但是你不能在你的程序中通过告诉python在内存中的哪个位置去寻找它来使用它;你必须给它一个名字。当你写作时

1a = np.array([[1,2],[3,4]])

您正在创建数组并创建引用该数组的名称a。从那时起,python就知道a指的是"内存地址0x123674283"(或其他)。python运行时中有一个包含所有这些信息的内部表(如果我记得正确的话,称为"符号表"),所以在上面一行python代码运行之后,这个表将包含

1

2

3...,

'a' : 0x123674283,

...

当您将一个变量的值赋给另一个变量时,例如

1b = a

python不会复制整个数组,因为如果它是一个大数组,则需要很长时间。相反,它会转到符号表,并将a的内存地址复制到b表中的新行。所以你最终

1

2

3

4

5...,

'a' : 0x123674283,

...,

'b' : 0x123674283,

...

你看,a和b实际上指的是内存中相同的位置,即相同的对象。您对其中一个所做的任何更改都将反映在另一个中,因为它们只是同一事物的两个名称。

如果要实际复制数组,则必须调用一个方法来显式执行该操作。numpy数组有一个copy方法,您可以仅用于此目的。所以如果你写

1b = a.copy()

然后,python将首先实际复制数组——也就是说,它留出了一个新的内存区域,比如在地址0x123904381处,然后转到内存地址0x123674283,并将数组的所有值从内存的后一部分复制到前一部分。所以你在记忆中的两个不同的地方有相同的内容。

1

2

3

4

5...,

'a' : 0x123674283,

...,

'b' : 0x123904381,

...

现在,当您更改b的一个元素时,该更改不会出现在a中,因为a和b不再指计算机内存的同一部分。由于阵列数据有两个独立的副本,因此可以更改其中一个而不影响另一个。

非常感谢您的精彩描述。不用说,这解决了问题,但我真的很感谢你花时间解释。你启发了我!

"python不会复制整个数组,因为如果它是一个大数组,则需要很长的时间。"—我想说,它所花的时间更少,如果不以这种方式实现,则需要引入一些类似于单独指针类型的东西,这些东西会使事情变得复杂。

简言之,变量赋值创建对现有对象的新引用。

1

2A = object # A points to object in memory

B = A # B points to the same object

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值