Python数据分析系列之Numpy常用操作第六篇

173 阅读2分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

Numpy中赋值操作有时候是数据复制(返回新对象),有时候却是引用.

下面的数组赋值运算是不会复制数据的,只是引用:

In [37]: data = np.arange(6)

In [38]: data.shape Out[38]: (6,)

In [39]: data Out[39]: array([0, 1, 2, 3, 4, 5])

In [40]: data2 = data

In [41]: data2 is data Out[41]: True

In [42]: data.resize(2,3)

In [43]: data Out[43]: array([[0, 1, 2], [3, 4, 5]])

In [44]: data2 Out[44]: array([[0, 1, 2], [3, 4, 5]])

Numpy的view方法(视图的方法)可以创建共享相同数据的不同数组, 改变某个值,共享这些数据的数组都会受到影响:

In [45]: data Out[45]: array([[0, 1, 2], [3, 4, 5]])

In [46]: data2 = data.view()

In [47]: data2 is data Out[47]: False

In [48]: data2.shape = 1,-1

In [49]: data Out[49]: array([[0, 1, 2], [3, 4, 5]])

In [50]: data2 Out[50]: array([[0, 1, 2, 3, 4, 5]])

In [51]: data2.base is data Out[51]: True

In [52]: data2[0, 2] = 999

In [53]: data Out[53]: array([[ 0, 1, 999], [ 3, 4, 5]])

In [54]: data2 Out[54]: array([[ 0, 1, 999, 3, 4, 5]])

数组切片也是返回一个视图,改变某个值,其他数组也会受影响
In [53]: data Out[53]: array([[ 0, 1, 999], [ 3, 4, 5]])

In [54]: data2 Out[54]: array([[ 0, 1, 999, 3, 4, 5]])

In [55]: data3 = data2[:, 0:2]

In [56]: data3 Out[56]: array([[0, 1]])

In [57]: data3[0,0] = 888

In [58]: data3 Out[58]: array([[888, 1]])

In [59]: data Out[59]: array([[888, 1, 999], [ 3, 4, 5]])

In [60]: data2 Out[60]: array([[888, 1, 999, 3, 4, 5]])

Numpy的copy方法可以完全拷贝一个数组副本,返回新的数组对象:

In [61]: data Out[61]: array([[888, 1, 999], [ 3, 4, 5]])

In [62]: data2 = data.copy()

In [63]: data2 Out[63]: array([[888, 1, 999], [ 3, 4, 5]])

In [64]: data2[0, 0] = 666

In [65]: data2 Out[65]: array([[666, 1, 999], [ 3, 4, 5]])

In [66]: data Out[66]: array([[888, 1, 999], [ 3, 4, 5]])

所以,如果不需要原数组只需要一小部分数据,应该使用切片获得视图后调用copy方法保存新数组后, 进行del 原数组进行释放内存。

In [66]: data Out[66]: array([[888, 1, 999], [ 3, 4, 5]])

In [67]: result = data[:, 0:2].copy()

In [68]: del data

In [69]: result Out[69]: array([[888, 1], [ 3, 4]])