《Python数据分析基础教程:NumPy学习指南(第2版)》笔记4:第二章 NumPy基础3——数组的组合、分割,数组转换为列表

第二章 NumPy基础3

本章示例代码中的输入和输出均来自IPython会话。

2.7 数组的组合

NumPy数组有水平组合、垂直组合和深度组合等多种组合方式,我们将使用vstackdstackhstackcolumn_stackrow_stack以及concatenate函数来完成数组的组合。

2.8 动手实践:组合数组

首先,我们来创建一些数组:

In [1]: import numpy as np
In [3]: a = np.arange(9).reshape(3,3)
In [4]: a
Out[4]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [5]: b = 2*a
In [6]: b
Out[6]:
array([[ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

(1) 水平组合

我们先从水平组合开始练习。将ndarray对象构成的元组作为参数,传给hstack函数。如下所示:

In [8]: np.hstack((a, b))
Out[8]:
array([[ 0,  1,  2,  0,  2,  4],
       [ 3,  4,  5,  6,  8, 10],
       [ 6,  7,  8, 12, 14, 16]])

我们也可以用concatenate函数来实现同样的效果,如下所示:

In [9]: np.concatenate((a, b), axis=1)
Out[9]:
array([[ 0,  1,  2,  0,  2,  4],
       [ 3,  4,  5,  6,  8, 10],
       [ 6,  7,  8, 12, 14, 16]])

《Python数据分析基础教程:NumPy学习指南(第2版)》笔记4:第二章 NumPy基础3——数组的组合、分割,数组转换为列表_第1张图片

(2) 垂直组合

垂直组合同样需要构造一个元组作为参数,只不过这次的函数变成了vstack。如下所示:

In [6]: np.vstack((a, b))
Out[6]:
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

同样,我们将concatenate函数的axis参数设置为0即可实现同样的效果。这也是axis参数的默认值:

In [8]: np.concatenate((a, b), axis = 0)
Out[8]:
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

《Python数据分析基础教程:NumPy学习指南(第2版)》笔记4:第二章 NumPy基础3——数组的组合、分割,数组转换为列表_第2张图片

(3) 深度组合

将相同的元组作为参数传给dstack函数,即可完成数组的深度组合。所谓深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合。举个例子,有若干张二维平面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起,这就形象地解释了什么是深度组合。

In [9]: np.dstack((a, b))
Out[9]:
array([[[ 0,  0],
        [ 1,  2],
        [ 2,  4]],

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

       [[ 6, 12],
        [ 7, 14],
        [ 8, 16]]])

(4) 列组合

column_stack函数对于一维数组将按列方向进行组合,如下所示:

In [10]: oned = np.arange(2)

In [11]: oned
Out[11]: array([0, 1])

In [12]: twice_oned = 2 * oned

In [13]: twice_oned
Out[13]: array([0, 2])

In [14]: np.column_stack((oned, twice_oned))
Out[14]:
array([[0, 0],
       [1, 2]])

而对于二维数组, column_stackhstack的效果是相同的:

In [15]: np.column_stack((a, b))
Out[15]:
array([[ 0,  1,  2,  0,  2,  4],
       [ 3,  4,  5,  6,  8, 10],
       [ 6,  7,  8, 12, 14, 16]])

In [16]: np.column_stack((a, b)) == np.hstack((a, b))
Out[16]:
array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True]])

是的,你猜对了!我们可以用==运算符来比较两个NumPy数组,是不是很简洁?

(5) 行组合

当然, NumPy中也有按行方向进行组合的函数,它就是row_stack。对于两个一维数组,将直接层叠起来组合成一个二维数组。

In [17]: np.row_stack((oned, twice_oned))
Out[17]:
array([[0, 1],
       [0, 2]])

对于二维数组, row_stackvstack的效果是相同的:

In [18]: np.row_stack((a, b))
Out[18]:
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

In [19]: np.row_stack((a,b)) == np.vstack((a, b))
Out[19]:
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])

2.9 数组的分割

NumPy数组可以进行水平、垂直或深度分割,相关的函数有hsplitvsplitdsplitsplit。我们可以将数组分割成相同大小的子数组,也可以指定原数组中需要分割的位置。

2.10 动手实践:分割数组

(1) 水平分割

下面的代码将把**数组沿着水平方向分割(按列分割)**为3个相同大小的子数组:

In [20]: a
Out[20]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [21]: np.hsplit(a, 3)
Out[21]:
[array([[0],
        [3],
        [6]]), array([[1],
        [4],
        [7]]), array([[2],
        [5],
        [8]])]

对同样的数组,调用split函数并在参数中指定参数axis=1,对比一下结果:

In [23]: np.split(a, 3, axis=1)
Out[23]:
[array([[0],
        [3],
        [6]]), array([[1],
        [4],
        [7]]), array([[2],
        [5],
        [8]])]

(2) 垂直分割

vsplit函数将把数组沿着垂直方向(按行分割)分割

In [24]: np.vsplit(a, 3)
Out[24]: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]

同样,调用split函数并在参数中指定参数axis=0,也可以得到同样的结果:

In [25]: np.split(a, 3, axis=0)
Out[25]: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]

(3) 深度分割

不出所料, dsplit函数将按深度方向分割数组。我们先创建一个三维数组:

In [26]: c = np.arange(27).reshape(3, 3, 3)

In [27]: c
Out[27]:
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]]])

In [28]: np.dsplit(c, 3)
Out[28]:
[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]]])]

2.11 数组的属性

除了shapedtype属性以外, ndarray对象还有很多其他的属性,在下面一一列出。

  • ndim属性,给出数组的维数,或数组轴的个数:
In [29]:  b
Out[29]:
array([[ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

In [30]: b.ndim
Out[30]: 2
  • size属性,给出数组元素的总个数,如下所示:
In [31]: b.size
Out[31]: 9
  • itemsize属性,给出数组中的元素在内存中所占的字节数:
In [32]: b.itemsize
Out[32]: 4
  • 如果你想知道整个数组所占的存储空间,可以用nbytes属性来查看。这个属性的值其实就是itemsizesize属性值的乘积
In [33]: b.nbytes
Out[33]: 36

In [34]: b.size * b.itemsize
Out[34]: 36
  • T属性的效果和transpose函数一样,如下所示:
In [35]: b.T
Out[35]:
array([[ 0,  6, 12],
       [ 2,  8, 14],
       [ 4, 10, 16]])

In [36]: b
Out[36]:
array([[ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16]])

对于一维数组,其T属性就是原数组

  • NumPy中,复数的虚部是用j表示的。例如,我们可以创建一个由复数构成的数组:
In [38]: b = np.array([1.j + 1, 2.j + 3])

In [39]: b
Out[39]: array([1.+1.j, 3.+2.j])
  • real属性,给出复数数组的实部。如果数组中只包含实数元素,则其real属性将输出原数组:
In [40]: b.real
Out[40]: array([1., 3.])
  • imag属性,给出复数数组的虚部:
In [41]: b.imag
Out[41]: array([1., 2.])
  • 如果数组中包含复数元素,则其数据类型自动变为复数型:
In [42]: b.dtype
Out[42]: dtype('complex128')

In [43]: b.dtype.str
Out[43]: '
  • flat属性将返回一个numpy.flatiter对象, 这是获得flatiter对象的唯一方式——我们无法访问flatiter的构造函数。这个所谓的“扁平迭代器”可以让我们像遍历一维数组一样去遍历任意的多维数组,如下所示:
In [45]: b = np.arange(4).reshape(2,2)

In [46]: f = b.flat

In [47]: f
Out[47]: <numpy.flatiter at 0x1aea0d05230>

In [49]: for item in f: print(item)
0
1
2
3

我们还可以用flatiter对象直接获取一个数组元素

In [50]: b.flat[2]
Out[50]: 2

或者获取多个元素:

In [51]: b.flat[[1,3]]
Out[51]: array([1, 3])

flat属性是一个可赋值的属性。对flat属性赋值将导致整个数组的元素都被覆盖:

In [52]: b.flat = 7

In [53]: b
Out[53]:
array([[7, 7],
       [7, 7]])

还可以对flat属性数组元素进行单独的赋值。

In [54]: b.flat[[1,3]] = 1

In [55]: b
Out[55]:
array([[7, 1],
       [7, 1]])

《Python数据分析基础教程:NumPy学习指南(第2版)》笔记4:第二章 NumPy基础3——数组的组合、分割,数组转换为列表_第3张图片

2.12 动手实践:数组转换为列表

我们可以使用tolist函数将NumPy数组转换成Python列表。
(1) 转换成列表:

In [57]: c = np.array([ 1.+1.j, 3.+2.j])

In [58]: c
Out[58]: array([1.+1.j, 3.+2.j])

In [59]: c.tolist()
Out[59]: [(1+1j), (3+2j)]

(2) astype函数可以在转换数组时指定数据类型:

In [60]: c
Out[60]: array([1.+1.j, 3.+2.j])

In [61]: c.astype(int)
C:\Users\Administrator\AppData\Local\Programs\Python\Python37\Scripts\ipython:1: ComplexWarning: Casting complex values to real discards the imaginary part
Out[61]: array([1, 3])

在上面将复数转换为整数的过程中,我们丢失了复数的虚部。 astype函数也可以接受数据类型为字符串的参数。使用正确的数据类型则不会再显示任何警告信息。

In [62]: b.astype('complex')
Out[62]:
array([[7.+0.j, 1.+0.j],
       [7.+0.j, 1.+0.j]])

你可能感兴趣的:(numpy,数组,组合,分割,列表)