1. 数值的组合
Numpy 数组有水平组合、垂直组合和深度组合等多种组合方式,我们将使用vstack、dstack、hstack、column_stack、row_stack以及concatenate函数来完成数组的组合。
实践如下:
(1) 水平组合 将ndarray对象构成的元组作为参数,传给hstack函数。如下所示:
a = np.arange(9).reshape(3, 3)
a
Out[65]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
b = 2 * a
b
Out[67]:
array([[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
np.hstack((a, b))
Out[68]:
array([[ 0, 1, 2, 0, 2, 4],
[ 3, 4, 5, 6, 8, 10],
[ 6, 7, 8, 12, 14, 16]])
使用concatenate 函数可以实现同样的效果,原理如图:
np.concatenate((a, b), axis = 1)
Out[69]:
array([[ 0, 1, 2, 0, 2, 4],
[ 3, 4, 5, 6, 8, 10],
[ 6, 7, 8, 12, 14, 16]])
(2) 垂直组合 垂直组合同样需要构造一个元组作为参数,需要用到vstack。
np.vstack((a, b))
Out[70]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
np.concatenate((a, b), axis = 0)
Out[71]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
同样将concatenate函数的axis参数设置为0即可实现同样的效果。(axis参数默认值为0)
(3) 深度组合 将相同元组作为参数传给 dstack函数,即可完成数组的深度组合。所谓深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合。
举个例子,有若干张二维平面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起,这就形象地解释了什么是深度组合。
np.dstack((a, b))
Out[72]:
array([[[ 0, 0],
[ 1, 2],
[ 2, 4]],
[[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 6, 12],
[ 7, 14],
[ 8, 16]]])
(4) 列组合 column_stack 函数对于一维数组将按列方向进行组合,如下所示:
oned = np.arange(2)
oned
Out[74]: array([0, 1])
twice_oned = 2 * oned
twice_oned
Out[76]: array([0, 2])
np.column_stack((oned, twice_oned))
Out[77]:
array([[0, 0],
[1, 2]])
而对于二维数组,column_stack 与 hstack 效果是相同的:
np.column_stack((a, b))
Out[78]:
array([[ 0, 1, 2, 0, 2, 4],
[ 3, 4, 5, 6, 8, 10],
[ 6, 7, 8, 12, 14, 16]])
np.column_stack((a, b)) == np.hstack((a, b))
Out[79]:
array([[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True]], dtype=bool)
可以用 == 运算符来比较两个NumPy 数组。 (5) 行组合 Numpy 中有按行方向进行组合的函数,即 row_stack。对于两个以为数组,将直接层叠起来组合成一个二维数组。
np.row_stack((oned, twice_oned))
Out[80]:
array([[0, 1],
[0, 2]])
对于二维数组,row_stack 与vstack 的效果是相同的:
np.row_stack((a, b))
Out[81]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
np.row_stack((a, b)) == np.vstack((a, b))
Out[82]:
array([[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True]], dtype=bool)
2 数组的维数切换
import numpy as np
b = np.arange(24).reshape(2,3,4)
b
Out[12]:
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]]])
(1) ravel 可以使用ravel 函数完成 展平的操作:
c = b.ravel()
c
Out[15]:
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])
不过,flatten函数会请求分配内存来保存结果,而ravel函数只是返回数组的一个视图(view):
import numpy as np
b = np.arange(24).reshape(2,3,4)
b
Out[5]:
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]]])
b.flatten()
Out[6]:
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])
(1) 水平分割 函数 hsplit,或使用split函数指定 参数 axis = 1, 操作如下:
a = np.arange(9).reshape(3, 3)
a
Out[8]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
np.hsplit(a, 3)
Out[9]:
[array([[0],
[3],
[6]]),
array([[1],
[4],
[7]]),
array([[2],
[5],
[8]])]
np.split(a, 3, axis = 1)
Out[10]:
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
(2) 垂直分割 vsplit 函数将把数组沿着垂直方向分割:
np.vsplit(a, 3)
Out[11]: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
np.split(a, 3, axis = 0)
Out[12]: [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
c = np.arange(27).reshape(3,3,3)
c
Out[17]:
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]]])
np.dsplit(c, 3)
Out[18]:
[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]]])]
4. 数组的属性
除了 shape 和dtype 属性以外,ndarray 还有很多其他的属性:
4.1 ndim 属性, 给出数组的维数,或数组轴的个数:
b = np.arange(24).reshape(2,3,4)
b
Out[25]:
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]]])
b.ndim
Out[26]: 3
b.reshape(2,12).ndim
Out[27]: 2
b.reshape(4,6).ndim
Out[28]: 2
b.flatten().ndim
Out[29]: 1
4.2 size 属性,给出数组元素的总个数,如下所示:
b.size
Out[30]: 24
4.3 itemsize属性,给出数组中的元素在内存中所占的字节数:
b.itemsize
Out[31]: 4
4.4 nbytes 属性查看整个数组所占的存储空间,这个属性值其实就是itemsize 和size 属性值的乘积:
b.nbytes
Out[32]: 96
4.5 T属性的效果和transpose函数一样,如下所示:
b.resize(6,4)
b
Out[34]:
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]])
b.T
Out[35]:
array([[ 0, 4, 8, 12, 16, 20],
[ 1, 5, 9, 13, 17, 21],
[ 2, 6, 10, 14, 18, 22],
[ 3, 7, 11, 15, 19, 23]])
b.transpose()
Out[36]:
array([[ 0, 4, 8, 12, 16, 20],
[ 1, 5, 9, 13, 17, 21],
[ 2, 6, 10, 14, 18, 22],
[ 3, 7, 11, 15, 19, 23]])
4.6 Numpy 中,复数的虚部用j 表示 :
b = np.array([1.j + 1, 2.j + 3])
b
Out[46]: array([ 1.+1.j, 3.+2.j])
b.real
Out[47]: array([ 1., 3.])
b.imag
Out[48]: array([ 1., 2.])
b.dtype
Out[49]: dtype('complex128')
4.7 flat属性返回一个numpy.flatiter对象,这是获得flatiter对象的唯一方式 -- ---我们无法访问flatiter的构造函数。这个所谓的“扁平迭代器”可让我们像遍历一维数组一样去遍历任意多维数组,如下所示:
b = np.arange(4).reshape(2, 2)
b
Out[52]:
array([[0, 1],
[2, 3]])
f = b.flat
f
Out[54]: <numpy.flatiter at 0x46901b0>
for item in f: print item
0
1
2
3
b.flat[2]
Out[56]: 2
b.flat[[1, 3]]
Out[57]: array([1, 3])
b.flat = 7
b
Out[59]:
array([[7, 7],
[7, 7]])
flat属性是一个可赋值的属性。对flat属性赋值将导致整个数组元素都被覆盖。
5. 数组的转换
可以使用tolist 函数将NumPy数组转换成Python列表。
5.1 转换成列表:
b = np.array([1.j + 1, 2.j + 3])
b
Out[61]: array([ 1.+1.j, 3.+2.j])
b.tolist()
Out[62]: [(1+1j), (3+2j)]
5.2 astype函数可以在转换数组时指定数据类型:
b.astype(int)
C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\start_ipython_kernel.py:1: ComplexWarning: Casting complex values to real discards the imaginary part
# -*- coding: utf-8 -*-
Out[63]: array([1, 3])