发布日期:2023-10-30 05:37 点击次数:178
[[416488]]北京赛车娱乐城
本文转载自微信公众号「Python中语社区」,作家Trauring。转载本文请干系Python中语社区公众号。
澳门新葡京赌场若是您使用 Python 的 NumPy 库,经常是因为您正在责罚占用大宗内存的大型数组。为了减少内存使用,您可能但愿尽量减少无须要的调换项。
宝马会彩票网NumPy 有一个内置功能,不错在许多常见情况下透明地实践此操作:内存视图。而且,此功能还不错驻扎数组被垃圾回收,从而导致更高的内存使用率。在某些情况下,它可能会导致无理,数据会以出东谈认识象的风光发生变异。
赌场娱乐城官网为了幸免这些问题,让咱们了解视图的职责旨趣以及对代码的影响。
规划常识:Python 列表在搜检 NumPy 数组和视图之前,让咱们筹商一个有点相似的数据结构:Python 列表。
运动策略Python 列表与 NumPy 数组相同,是贯串的内存块。当你对一个 Python 列表进行切良晌,你会获得一个弥散不同的列表,这意味着你正在分派一块新的内存:
>>> 北京赛车娱乐城from psutil import Process >>> Process().memory_info().rss 12247040 >>> list1 = [None] * 1_000_000 >>> Process().memory_info().rss 20463616 >>> list2 = list1[:500_000] >>> Process().memory_info().rss 24580096
切片列表分派了更多内存。由于第二个列表是一个零丁的副本,若是咱们更变它,这不会影响第一个列表:
>>> list2[0] = "abc" >>> print(list2[0]) abc >>> print(list1[0]) None
恰当,复制到第二个列表中的数据是指向 Python 对象的指针,而不是对象自己的内容。因此,即使列表自己不同,底层对象仍然在两者之间进行分享。
切良晌 NumPy 数组并不进行复制NumPy 数组的职责风光不同。因为假定您可能正在责罚绝顶大的数组,是以许多操作不会复制数组,它们仅仅让您搜检原始数组指向的吞并贯串内存块。
皇冠客服飞机:@seo3687
第一个按捺是切片不会分派更多内存,因为它仅仅原始数组的视图:
>>> from psutil import Process >>> import numpy as np >>> arr = np.arange(0, 1_000_000) >>> Process().memory_info().rss 37810176 >>> view = arr[:500_000] >>> Process().memory_info().rss 37810176
视图对象看起来像一个 500,000 长的 int64 数组,因此若是它是一个新数组,它将分派约莫 4MB 的内存。但它仅仅针对吞并个原始数组的一个视图,是以不需要突出的内存。
博彩入门教程从技能上来说,可能会为视图对象本要素配一小部安分存,但这不错忽略不计,除非您有好多视图对象。在这种情况下,RSS(常驻内存)度量中莫得出现新内存,因为 Python 事先分派了更大的内存块,然后用小的 Python 对象填充这些块。
视图导致内存表示使用视图的效果之一是您可能会表示内存,而不是节俭内存。这是因为视图不错驻扎原始数组被垃圾回收 - 对通盘数组来说。
假定您一经决定只需要使用大数组的一小部分:
>>> import numpy as np >>> from psutil import Process >>> arr = np.arange(0, 100_000_000) >>> Process().memory_info().rss 830181376 >>> small_slice = arr[:10] >>> del arr >>> Process().memory_info().rss 830111744
若是这是一个 Python 列表,欧博百家乐投注删除原始对象将开释内存。然则,在这种情况下,即使咱们莫得对数组的径直援用,视图仍然不错起作用,这意味着内存莫得被开释,即使咱们只对其中的一小部分感酷好酷好。
您本体上不错通过视图看望原始数组:
网站拥有多样化博彩游戏赛事直播,全面、优质博彩攻略技巧分享,广大博彩爱好者提供博彩服务。平台安全稳定,操作简便,充值提款便捷,您带来最佳博彩体验最高博彩收益。>>> small_slice array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> small_slice.base array([0, 1, 2, ..., 99999997, 99999998, 99999999])
按捺,惟有当咱们删除整个视图时,原始数组的内存才会被开释:
>>> del small_slice >>> Process().memory_info().rss 29642752其他更变
使用视图的另一个效果是修改视图会更变原始数组。回念念一下,关于 Python 列表,修改切片按捺不会修改原始列表,因为新对象是一个副本:
>>> l = [1, 2, 3] >>> l2 = l[:] >>> l2[0] = 17 >>> l2 [17, 2, 3] >>> l [1, 2, 3]
使用 NumPy 视图后,更变视图如实更变了原始对象,它们王人指向吞并个内存地址:
>>> arr = np.array([1, 2, 3]) >>> view = arr[:] >>> view[0] = 17 >>> view array([17, 2, 3]) >>> arr array([17, 2, 3])
这个按捺不是咱们念念要的!
由于某些 NumPy API 可能会把柄情况复返视图或副本,因此更有可能发生不测变化。举例,某些切片按捺可能不是视图:
>>> arr = np.array([1, 2, 3]) >>> arr2 = arr[:] >>> arr2.base is arr True >>> arr3 = arr[[True, False, True]] >>> arr3.base is arr False
更变 arr2 也会更变 arr,但更变 arr3 不会更变 arr。
使用 copy() 进行显式复制当您不念念援用原始内存时,显式复制允许您创建一个新数组。这关于驻扎更变很灵验,况且在您不念念将原始数组保留在内存中的情况下也很灵验:
>>> arr = np.arange(0, 100_000_000) >>> Process().memory_info().rss 829464576 >>> small_slice = arr[:10].copy() >>> del arr >>> Process().memory_info().rss 29700096 >>> print(small_slice.base) None
在这种情况下,删除 arr 开释了内存,因为 small_slice 是副本,而不是视图。
十四届全国人大常委会第五次会议于8月28日至9月1日在北京举行,本次会议对《中华人民共和国公司法 (修订草案三次审议稿)》进行了审议,并于2023年9月1日起公开征求意见。
皇冠体育 重心:高效安全地使用视图鉴于多样 NumPy API 会自动复返视图,您需要在编写代码时筹商它们:
在文档中恰当 API 是否会复返视图、副本或两者。 若是您念念从内存中断根一个大数组,请确保不仅莫得径直援用它,而且莫得援用它的视图。 若是你要更变一个数组,确保它不会因为它本体上是一个视图而不测更变其他一些数组。 若是您不需要视图,请使用 copy() 要津。