简体   繁体   English

对于numpy数组,赋值给array和array[:]有区别吗?

[英]For a numpy array, is there a difference between assigning to array and array[:]?

This a quite basic and subtle question that I've never considered before, but I recently stumbled across the notation a[:] again and this time it caught my attention.这是一个我以前从未考虑过的非常基本和微妙的问题,但我最近再次偶然发现了符号a[:] ,这次它引起了我的注意。 Consider the two following examples:考虑以下两个示例:

Example A例一

a     = numpy.zeros(10)
vals  = numpy.arange(10)
a     = vals**2

Example B例子二

a     = numpy.zeros(10)
vals  = numpy.arange(10)
a[:]  = vals**2

The difference is solely in the assignment in the last line.不同之处仅在于最后一行的分配。 For years I've never thought about the difference between the two.多年来,我从未想过两者之间的区别。 But is there a difference?但是有区别吗? Does B use less memory by directly assigning the values to the existing array vs. creating another temporary array in example A? B 是否通过直接将值分配给现有数组而不是在示例 A 中创建另一个临时数组来使用更少的 memory? Or are the two identical after all (even under the hood)?或者两者到底是相同的(甚至在引擎盖下)?

Yes, the difference is that a = changes the value associated with the name a and a[:] = internally mutates a .是的,不同之处在于a =更改与名称a关联的值,而a[:] =在内部改变a

Mutating a[:] internally should take up a little less memory, since the original value of a doesn't need to be separately garbage collected after the assignment (as no names point to it anymore).在内部改变a[:]应该占用少一点 memory,因为a的原始值不需要在分配后单独进行垃圾收集(因为不再有名称指向它)。

This also stands for other Python objects, collections, etc, that support slice assignment (and in fact, the fact the same object is modified has an important use case with filtering directories in os.walk() ).这也代表支持切片分配的其他 Python 对象、collections 等(事实上,修改相同的 object 具有os.walk()中过滤目录的重要用例)。

However, your use case will probably be best served with just但是,您的用例可能最好只使用

a = numpy.arange(10)  # (or however you'd get the values to square)
a **= 2

since Numpy can optimize the __ipow__ inline power operation to happen all in-place and there would be no additional allocation for vals ** 2 before it's put in its place.因为 Numpy 可以优化__ipow__内联电源操作以全部就地发生,并且在将其放置到位之前不会为vals ** 2进行额外分配。

Result of the first:第一个结果:

[ 0  1  4  9 16 25 36 49 64 81]

Result of the second:第二个结果:

[ 0.  1.  4.  9. 16. 25. 36. 49. 64. 81.]

Do those really look identical to you?那些看起来真的和你一模一样吗?

Assigning into an existing array keeps its dtype .分配到现有数组中会保留其dtype Assigning just to the variable instead gets you whatever the new value has.只分配给变量而不是让你得到任何新值。

Also, if you had another reference to the original array, ie, let's say you had done b = a , then your first code won't affect b at all while your second code will.此外,如果您有另一个对原始数组的引用,即假设您已经完成了b = a ,那么您的第一个代码根本不会影响b而您的第二个代码会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM