NumPy简明教程(二、数组3)

前两篇文章对NumPy数组做了基本的介绍,本篇文章对NumPy数组进行较深入的探讨。首先介绍自定义类型的数组,接着数组的组合,最后介绍数组复制方面的问题。

自定义结构数组

通过NumPy也可以定义像C语言那样的结构类型。在NumPy中定义结构的方法如下:

定义结构类型名称;定义字段名称,标明字段数据类型。

[python] view plain copy
print ?
  1. student= dtype({‘names’:[‘name’‘age’‘weight’], ‘formats’:[‘S32’‘i’,‘f’]}, align = True)  
student= dtype({'names':['name', 'age', 'weight'], 'formats':['S32', 'i','f']}, align = True)

这里student是自定义结构类型的名称,使用dtype函数创建,在第一个参数中,’names’’formats’不能改变,names中列出的是结构中字段名称,formats中列出的是对应字段的数据类型。S32表示32字节长度的字符串,i表示32位的整数,f表示32位长度的浮点数。最后一个参数为True时,表示要求进行内存对齐。

字段中使用NumPy的字符编码来表示数据类型。更详细的数据类型见下表。

数据类型 字符编码
整数 i
无符号整数 u
单精度浮点数 f
双精度浮点数 d
布尔值 b
复数 D
字符串 S
Unicode U
Void V
在定义好结构类型之后,就可以定义以该类型为元素的数组了

[python] view plain copy
print ?
  1. a= array([(“Zhang”, 3265.5), (“Wang”, 2455.2)], dtype =student)  
a= array([(“Zhang”, 32, 65.5), (“Wang”, 24, 55.2)], dtype =student)

除了在每个元素中依次列出对应字段的数据外,还需要在array函数中最后一个参数指定其所对应的数据类型。

注:例子来源于张若愚的Python科学计算艺术的29页。更多关于dtype的内容请参考《NumPy for Beginner》一书的第二章。

组合函数

这里介绍以不同的方式组合函数。首先创建两个数组:

[python] view plain copy
print ?
  1. >>> a = arange(9).reshape(3,3)  
  2. >>> a  
  3. array([[012],  
  4.            [345],  
  5.            [678]])  
  6. >>> b = 2 * a  
  7. >>> b  
  8. array([[ 024],  
  9.        [ 6810],  
  10.        [121416]])  
>>> a = arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
>>> b = 2 * a
>>> b
array([[ 0, 2, 4],
       [ 6, 8, 10],
       [12, 14, 16]])

水平组合

[python] view plain copy
print ?
  1. >>> hstack((a, b))  
  2. array([[ 012024],  
  3.        [ 3456810],  
  4.        [ 678121416]])  
>>> hstack((a, b))
array([[ 0, 1, 2, 0, 2, 4],
       [ 3, 4, 5, 6, 8, 10],
       [ 6, 7, 8, 12, 14, 16]])
也可通过concatenate函数 并指定相应的轴来获得这一效果:
[python] view plain copy
print ?
  1. >>> concatenate((a, b), axis=1)  
  2. array([[ 012024],  
  3.        [ 3456810],  
  4.        [ 678121416]])  
>>> concatenate((a, b), axis=1)
array([[ 0, 1, 2, 0, 2, 4],
       [ 3, 4, 5, 6, 8, 10],
       [ 6, 7, 8, 12, 14, 16]])

垂直组合

[python] view plain copy
print ?
  1. >>> vstack((a, b))  
  2. array([[ 012],  
  3.        [ 345],  
  4.        [ 678],   
  5.        [ 024],  
  6.        [ 6810],  
  7.        [121416]])  
>>> vstack((a, b))
array([[ 0, 1, 2],
       [ 3, 4, 5],
       [ 6, 7, 8], 
       [ 0, 2, 4],
       [ 6, 8, 10],
       [12, 14, 16]])
同样,可通过concatenate函数,并指定相应的轴来获得这一效果。
[python] view plain copy
print ?
  1. >>> concatenate((a, b), axis=0)  
  2. array([[ 012],  
  3.        [ 345],  
  4.        [ 678],  
  5.        [ 024],  
  6.        [ 6810],  
  7.        [121416]])  
>>> concatenate((a, b), axis=0)
array([[ 0, 1, 2],
       [ 3, 4, 5],
       [ 6, 7, 8],
       [ 0, 2, 4],
       [ 6, 8, 10],
       [12, 14, 16]])

深度组合

另外,还有深度方面的组合函数dstack。顾名思义,就是在数组的第三个轴(即深度)上组合。如下:

[python] view plain copy
print ?
  1. >>> dstack((a, b))  
  2. array([[[ 00],  
  3.         [ 12],  
  4.         [ 24]],  
  5.   
  6.        [[ 36],  
  7.         [ 48],  
  8.         [ 510]],  
  9.   
  10.        [[ 612],  
  11.         [ 714],  
  12.         [ 816]]])  
>>> dstack((a, b))
array([[[ 0, 0],
        [ 1, 2],
        [ 2, 4]],

       [[ 3, 6],
        [ 4, 8],
        [ 5, 10]],

       [[ 6, 12],
        [ 7, 14],
        [ 8, 16]]])
仔细观察,发现对应的元素都组合成一个新的列表,该列表作为新的数组的元素。

行组合

行组合可将多个一维数组作为新数组的每一行进行组合:

[python] view plain copy
print ?
  1. >>> one = arange(2)  
  2. >>> one  
  3. array([01])  
  4. >>> two = one + 2  
  5. >>> two  
  6. array([23])  
  7. >>> row_stack((one, two))  
  8. array([[01],  
  9.        [23]])  
>>> one = arange(2)
>>> one
array([0, 1])
>>> two = one + 2
>>> two
array([2, 3])
>>> row_stack((one, two))
array([[0, 1],
       [2, 3]])

对于2维数组,其作用就像垂直组合一样。

列组合

列组合的效果应该很清楚了。如下:

[python] view plain copy
print ?
  1. >>> column_stack((oned, twiceoned))  
  2. array([[02],  
  3.        [13]])  
>>> column_stack((oned, twiceoned))
array([[0, 2],
       [1, 3]])
对于2维数组,其作用就像水平组合一样。

分割数组

在NumPy中,分割数组的函数有hsplit、vsplit、dsplit和split。可将数组分割成相同大小的子数组,或指定原数组分割的位置。

水平分割

[python] view plain copy
print ?
  1. >>> a = arange(9).reshape(3,3)  
  2. >>> a  
  3. array([[012],  
  4.        [345],  
  5.        [678]])  
  6. >>> hsplit(a, 3)  
  7. [array([[0],  
  8.        [3],  
  9.        [6]]),  
  10.  array([[1],  
  11.        [4],  
  12.        [7]]),  
  13.  array([[2],  
  14.        [5],  
  15.        [8]])]  
>>> a = arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> hsplit(a, 3)
[array([[0],
       [3],
       [6]]),
 array([[1],
       [4],
       [7]]),
 array([[2],
       [5],
       [8]])]
也调用split函数并指定轴为1来获得这样的效果:
[python] view plain copy
print ?
  1. split(a, 3, axis=1)  
split(a, 3, axis=1)

垂直分割

垂直分割是沿着垂直的轴切分数组:

[python] view plain copy
print ?
  1. >>> vsplit(a, 3)  
  2. >>> [array([[012]]), array([[345]]), array([[678]])]  
>>> vsplit(a, 3)
>>> [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
同样,也可通过solit函数并指定轴为1来获得这样的效果:
[python] view plain copy
print ?
  1. >>> split(a, 3, axis=0)  
>>> split(a, 3, axis=0)

面向深度的分割

dsplit函数使用的是面向深度的分割方式:

[python] view plain copy
print ?
  1. >>> c = arange(27).reshape(333)  
  2. >>> c  
  3. array([[[ 0,  1,  2],  
  4.         [ 3,  4,  5],  
  5.         [ 6,  7,  8]],  
  6.   
  7.        [[ 91011],  
  8.         [121314],  
  9.         [151617]],  
  10.   
  11.        [[181920],  
  12.         [212223],  
  13.         [242526]]])  
  14. >>> dsplit(c, 3)  
  15. [array([[[ 0],  
  16.         [ 3],  
  17.         [ 6]],  
  18.   
  19.        [[ 9],  
  20.         [12],  
  21.         [15]],  
  22.   
  23.        [[18],  
  24.         [21],  
  25.         [24]]]),  
  26.  array([[[ 1],  
  27.         [ 4],  
  28.         [ 7]],  
  29.   
  30.        [[10],  
  31.         [13],  
  32.         [16]],  
  33.   
  34.        [[19],  
  35.         [22],  
  36.         [25]]]),  
  37.  array([[[ 2],  
  38.         [ 5],  
  39.         [ 8]],  
  40.   
  41.        [[11],  
  42.         [14],  
  43.         [17]],  
  44.   
  45.        [[20],  
  46.         [23],  
  47.         [26]]])]  
>>> c = arange(27).reshape(3, 3, 3)
>>> c
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])
>>> dsplit(c, 3)
[array([[[ 0],
        [ 3],
        [ 6]],

       [[ 9],
        [12],
        [15]],

       [[18],
        [21],
        [24]]]),
 array([[[ 1],
        [ 4],
        [ 7]],

       [[10],
        [13],
        [16]],

       [[19],
        [22],
        [25]]]),
 array([[[ 2],
        [ 5],
        [ 8]],

       [[11],
        [14],
        [17]],

       [[20],
        [23],
        [26]]])]

复制和镜像(View

   当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:

完全不复制

   简单的赋值,而不复制数组对象或它们的数据。

[python] view plain copy
print ?
  1. >>> a = arange(12)  
  2. >>> b = a      #不创建新对象  
  3. >>> b is a           # a和b是同一个数组对象的两个名字  
  4. True  
  5. >>> b.shape = 3,4    #也改变了a的形状  
  6. >>> a.shape  
  7. (34)  
>>> a = arange(12)
>>> b = a      #不创建新对象
>>> b is a           # a和b是同一个数组对象的两个名字
True
>>> b.shape = 3,4    #也改变了a的形状
>>> a.shape
(3, 4)

    Python 传递不定对象作为参考4,所以函数调用不拷贝数组。

[python] view plain copy
print ?
  1. >>> def f(x):  
  2. …     print id(x)  
  3. …  
  4. >>> id(a)       #id是一个对象的唯一标识  
  5. 148293216  
  6. >>> f(a)  
  7. 148293216  
>>> def f(x):
...     print id(x)
...
>>> id(a)       #id是一个对象的唯一标识
148293216
>>> f(a)
148293216

视图(view)和浅复制

   不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。

[python] view plain copy
print ?
  1. >>> c = a.view()  
  2. >>> c is a  
  3. False  
  4. >>> c.base is a      #c是a持有数据的镜像  
  5. True  
  6. >>> c.flags.owndata  
  7. False  
  8. >>>  
  9. >>> c.shape = 2,6    # a的形状没变  
  10. >>> a.shape  
  11. (34)  
  12. >>> c[0,4] = 1234        #a的数据改变了  
  13. >>> a  
  14. array([[   0,    1,    2,    3],  
  15.        [1234,    5,    6,    7],  
  16.        [   8,    9,   10,   11]])  
>>> c = a.view()
>>> c is a
False
>>> c.base is a      #c是a持有数据的镜像
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6    # a的形状没变
>>> a.shape
(3, 4)
>>> c[0,4] = 1234        #a的数据改变了
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])
切片数组返回它的一个视图:
[python] view plain copy
print ?
  1. >>> s = a[ : , 1:3]     # 获得每一行1,2处的元素  
  2. >>> s[:] = 10           # s[:] 是s的镜像。注意区别s=10 and s[:]=10  
  3. >>> a  
  4. array([[   0,   10,   10,    3],  
  5.        [1234,   10,   10,    7],  
  6.        [   8,   10,   10,   11]])  
>>> s = a[ : , 1:3]     # 获得每一行1,2处的元素
>>> s[:] = 10           # s[:] 是s的镜像。注意区别s=10 and s[:]=10
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

深复制

   这个复制方法完全复制数组和它的数据。

[python] view plain copy
print ?
  1. >>> d = a.copy()       #创建了一个含有新数据的新数组对象  
  2. >>> d is a  
  3. False  
  4. >>> d.base is a        #d和a现在没有任何关系  
  5. False  
  6. >>> d[0,0] = 9999  
  7. >>> a  
  8. array([[   0,   10,   10,    3],  
  9.        [1234,   10,   10,    7],  
  10.        [   8,   10,   10,   11]])  
>>> d = a.copy()       #创建了一个含有新数据的新数组对象
>>> d is a
False
>>> d.base is a        #d和a现在没有任何关系
False
>>> d[0,0] = 9999
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

参考文献:

《Python科学计算》
《Tentative NumPy Tutorial》
《NumPy for Beginner》


前两篇文章对NumPy数组做了基本的介绍,本篇文章对NumPy数组进行较深入的探讨。首先介绍自定义类型的数组,接着数组的组合,最后介绍数组复制方面的问题。

自定义结构数组

通过NumPy也可以定义像C语言那样的结构类型。在NumPy中定义结构的方法如下:

定义结构类型名称;定义字段名称,标明字段数据类型。

[python] view plain copy
print ?
  1. student= dtype({‘names’:[‘name’‘age’‘weight’], ‘formats’:[‘S32’‘i’,‘f’]}, align = True)  
student= dtype({'names':['name', 'age', 'weight'], 'formats':['S32', 'i','f']}, align = True)

这里student是自定义结构类型的名称,使用dtype函数创建,在第一个参数中,’names’’formats’不能改变,names中列出的是结构中字段名称,formats中列出的是对应字段的数据类型。S32表示32字节长度的字符串,i表示32位的整数,f表示32位长度的浮点数。最后一个参数为True时,表示要求进行内存对齐。

字段中使用NumPy的字符编码来表示数据类型。更详细的数据类型见下表。

数据类型 字符编码
整数 i
无符号整数 u
单精度浮点数 f
双精度浮点数 d
布尔值 b
复数 D
字符串 S
Unicode U
Void V
在定义好结构类型之后,就可以定义以该类型为元素的数组了

[python] view plain copy
print ?
  1. a= array([(“Zhang”, 3265.5), (“Wang”, 2455.2)], dtype =student)  
a= array([(“Zhang”, 32, 65.5), (“Wang”, 24, 55.2)], dtype =student)

除了在每个元素中依次列出对应字段的数据外,还需要在array函数中最后一个参数指定其所对应的数据类型。

注:例子来源于张若愚的Python科学计算艺术的29页。更多关于dtype的内容请参考《NumPy for Beginner》一书的第二章。

组合函数

这里介绍以不同的方式组合函数。首先创建两个数组:

[python] view plain copy
print ?
  1. >>> a = arange(9).reshape(3,3)  
  2. >>> a  
  3. array([[012],  
  4.            [345],  
  5.            [678]])  
  6. >>> b = 2 * a  
  7. >>> b  
  8. array([[ 024],  
  9.        [ 6810],  
  10.        [121416]])  
>>> a = arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
>>> b = 2 * a
>>> b
array([[ 0, 2, 4],
       [ 6, 8, 10],
       [12, 14, 16]])

水平组合

[python] view plain copy
print ?
  1. >>> hstack((a, b))  
  2. array([[ 012024],  
  3.        [ 3456810],  
  4.        [ 678121416]])  
>>> hstack((a, b))
array([[ 0, 1, 2, 0, 2, 4],
       [ 3, 4, 5, 6, 8, 10],
       [ 6, 7, 8, 12, 14, 16]])
也可通过concatenate函数 并指定相应的轴来获得这一效果:
[python] view plain copy
print ?
  1. >>> concatenate((a, b), axis=1)  
  2. array([[ 012024],  
  3.        [ 3456810],  
  4.        [ 678121416]])  
>>> concatenate((a, b), axis=1)
array([[ 0, 1, 2, 0, 2, 4],
       [ 3, 4, 5, 6, 8, 10],
       [ 6, 7, 8, 12, 14, 16]])

垂直组合

[python] view plain copy
print ?
  1. >>> vstack((a, b))  
  2. array([[ 012],  
  3.        [ 345],  
  4.        [ 678],   
  5.        [ 024],  
  6.        [ 6810],  
  7.        [121416]])  
>>> vstack((a, b))
array([[ 0, 1, 2],
       [ 3, 4, 5],
       [ 6, 7, 8], 
       [ 0, 2, 4],
       [ 6, 8, 10],
       [12, 14, 16]])
同样,可通过concatenate函数,并指定相应的轴来获得这一效果。
[python] view plain copy
print ?
  1. >>> concatenate((a, b), axis=0)  
  2. array([[ 012],  
  3.        [ 345],  
  4.        [ 678],  
  5.        [ 024],  
  6.        [ 6810],  
  7.        [121416]])  
>>> concatenate((a, b), axis=0)
array([[ 0, 1, 2],
       [ 3, 4, 5],
       [ 6, 7, 8],
       [ 0, 2, 4],
       [ 6, 8, 10],
       [12, 14, 16]])

深度组合

另外,还有深度方面的组合函数dstack。顾名思义,就是在数组的第三个轴(即深度)上组合。如下:

[python] view plain copy
print ?
  1. >>> dstack((a, b))  
  2. array([[[ 00],  
  3.         [ 12],  
  4.         [ 24]],  
  5.   
  6.        [[ 36],  
  7.         [ 48],  
  8.         [ 510]],  
  9.   
  10.        [[ 612],  
  11.         [ 714],  
  12.         [ 816]]])  
>>> dstack((a, b))
array([[[ 0, 0],
        [ 1, 2],
        [ 2, 4]],

       [[ 3, 6],
        [ 4, 8],
        [ 5, 10]],

       [[ 6, 12],
        [ 7, 14],
        [ 8, 16]]])
仔细观察,发现对应的元素都组合成一个新的列表,该列表作为新的数组的元素。

行组合

行组合可将多个一维数组作为新数组的每一行进行组合:

[python] view plain copy
print ?
  1. >>> one = arange(2)  
  2. >>> one  
  3. array([01])  
  4. >>> two = one + 2  
  5. >>> two  
  6. array([23])  
  7. >>> row_stack((one, two))  
  8. array([[01],  
  9.        [23]])  
>>> one = arange(2)
>>> one
array([0, 1])
>>> two = one + 2
>>> two
array([2, 3])
>>> row_stack((one, two))
array([[0, 1],
       [2, 3]])

对于2维数组,其作用就像垂直组合一样。

列组合

列组合的效果应该很清楚了。如下:

[python] view plain copy
print ?
  1. >>> column_stack((oned, twiceoned))  
  2. array([[02],  
  3.        [13]])  
>>> column_stack((oned, twiceoned))
array([[0, 2],
       [1, 3]])
对于2维数组,其作用就像水平组合一样。

分割数组

在NumPy中,分割数组的函数有hsplit、vsplit、dsplit和split。可将数组分割成相同大小的子数组,或指定原数组分割的位置。

水平分割

[python] view plain copy
print ?
  1. >>> a = arange(9).reshape(3,3)  
  2. >>> a  
  3. array([[012],  
  4.        [345],  
  5.        [678]])  
  6. >>> hsplit(a, 3)  
  7. [array([[0],  
  8.        [3],  
  9.        [6]]),  
  10.  array([[1],  
  11.        [4],  
  12.        [7]]),  
  13.  array([[2],  
  14.        [5],  
  15.        [8]])]  
>>> a = arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> hsplit(a, 3)
[array([[0],
       [3],
       [6]]),
 array([[1],
       [4],
       [7]]),
 array([[2],
       [5],
       [8]])]
也调用split函数并指定轴为1来获得这样的效果:
[python] view plain copy
print ?
  1. split(a, 3, axis=1)  
split(a, 3, axis=1)

垂直分割

垂直分割是沿着垂直的轴切分数组:

[python] view plain copy
print ?
  1. >>> vsplit(a, 3)  
  2. >>> [array([[012]]), array([[345]]), array([[678]])]  
>>> vsplit(a, 3)
>>> [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
同样,也可通过solit函数并指定轴为1来获得这样的效果:
[python] view plain copy
print ?
  1. >>> split(a, 3, axis=0)  
>>> split(a, 3, axis=0)

面向深度的分割

dsplit函数使用的是面向深度的分割方式:

[python] view plain copy
print ?
  1. >>> c = arange(27).reshape(333)  
  2. >>> c  
  3. array([[[ 0,  1,  2],  
  4.         [ 3,  4,  5],  
  5.         [ 6,  7,  8]],  
  6.   
  7.        [[ 91011],  
  8.         [121314],  
  9.         [151617]],  
  10.   
  11.        [[181920],  
  12.         [212223],  
  13.         [242526]]])  
  14. >>> dsplit(c, 3)  
  15. [array([[[ 0],  
  16.         [ 3],  
  17.         [ 6]],  
  18.   
  19.        [[ 9],  
  20.         [12],  
  21.         [15]],  
  22.   
  23.        [[18],  
  24.         [21],  
  25.         [24]]]),  
  26.  array([[[ 1],  
  27.         [ 4],  
  28.         [ 7]],  
  29.   
  30.        [[10],  
  31.         [13],  
  32.         [16]],  
  33.   
  34.        [[19],  
  35.         [22],  
  36.         [25]]]),  
  37.  array([[[ 2],  
  38.         [ 5],  
  39.         [ 8]],  
  40.   
  41.        [[11],  
  42.         [14],  
  43.         [17]],  
  44.   
  45.        [[20],  
  46.         [23],  
  47.         [26]]])]  
>>> c = arange(27).reshape(3, 3, 3)
>>> c
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])
>>> dsplit(c, 3)
[array([[[ 0],
        [ 3],
        [ 6]],

       [[ 9],
        [12],
        [15]],

       [[18],
        [21],
        [24]]]),
 array([[[ 1],
        [ 4],
        [ 7]],

       [[10],
        [13],
        [16]],

       [[19],
        [22],
        [25]]]),
 array([[[ 2],
        [ 5],
        [ 8]],

       [[11],
        [14],
        [17]],

       [[20],
        [23],
        [26]]])]

复制和镜像(View

   当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:

完全不复制

   简单的赋值,而不复制数组对象或它们的数据。

[python] view plain copy
print ?
  1. >>> a = arange(12)  
  2. >>> b = a      #不创建新对象  
  3. >>> b is a           # a和b是同一个数组对象的两个名字  
  4. True  
  5. >>> b.shape = 3,4    #也改变了a的形状  
  6. >>> a.shape  
  7. (34)  
>>> a = arange(12)
>>> b = a      #不创建新对象
>>> b is a           # a和b是同一个数组对象的两个名字
True
>>> b.shape = 3,4    #也改变了a的形状
>>> a.shape
(3, 4)

    Python 传递不定对象作为参考4,所以函数调用不拷贝数组。

[python] view plain copy
print ?
  1. >>> def f(x):  
  2. …     print id(x)  
  3. …  
  4. >>> id(a)       #id是一个对象的唯一标识  
  5. 148293216  
  6. >>> f(a)  
  7. 148293216  
>>> def f(x):
...     print id(x)
...
>>> id(a)       #id是一个对象的唯一标识
148293216
>>> f(a)
148293216

视图(view)和浅复制

   不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。

[python] view plain copy
print ?
  1. >>> c = a.view()  
  2. >>> c is a  
  3. False  
  4. >>> c.base is a      #c是a持有数据的镜像  
  5. True  
  6. >>> c.flags.owndata  
  7. False  
  8. >>>  
  9. >>> c.shape = 2,6    # a的形状没变  
  10. >>> a.shape  
  11. (34)  
  12. >>> c[0,4] = 1234        #a的数据改变了  
  13. >>> a  
  14. array([[   0,    1,    2,    3],  
  15.        [1234,    5,    6,    7],  
  16.        [   8,    9,   10,   11]])  
>>> c = a.view()
>>> c is a
False
>>> c.base is a      #c是a持有数据的镜像
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6    # a的形状没变
>>> a.shape
(3, 4)
>>> c[0,4] = 1234        #a的数据改变了
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])
切片数组返回它的一个视图:
[python] view plain copy
print ?
  1. >>> s = a[ : , 1:3]     # 获得每一行1,2处的元素  
  2. >>> s[:] = 10           # s[:] 是s的镜像。注意区别s=10 and s[:]=10  
  3. >>> a  
  4. array([[   0,   10,   10,    3],  
  5.        [1234,   10,   10,    7],  
  6.        [   8,   10,   10,   11]])  
>>> s = a[ : , 1:3]     # 获得每一行1,2处的元素
>>> s[:] = 10           # s[:] 是s的镜像。注意区别s=10 and s[:]=10
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

深复制

   这个复制方法完全复制数组和它的数据。

[python] view plain copy
print ?
  1. >>> d = a.copy()       #创建了一个含有新数据的新数组对象  
  2. >>> d is a  
  3. False  
  4. >>> d.base is a        #d和a现在没有任何关系  
  5. False  
  6. >>> d[0,0] = 9999  
  7. >>> a  
  8. array([[   0,   10,   10,    3],  
  9.        [1234,   10,   10,    7],  
  10.        [   8,   10,   10,   11]])  
>>> d = a.copy()       #创建了一个含有新数据的新数组对象
>>> d is a
False
>>> d.base is a        #d和a现在没有任何关系
False
>>> d[0,0] = 9999
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

参考文献:

《Python科学计算》
《Tentative NumPy Tutorial》
《NumPy for Beginner》


猜你喜欢

转载自blog.csdn.net/junchengberry/article/details/80723269
今日推荐