NumPy,是Numerical Python的简称,它是目前Python数值计算中最为重要的基础包。使用numpy
模块处理含有大量数组的数据非常有效:
In [1]: import numpy as np
In [3]: arr = np.arange(1000000)
In [4]: l = list(range(1000000))
In [3]: %time for _ in range(10): arr * 2
# Wall time: 28.9 ms
In [6]: %time for _ in range(10): l = [x * 2 for x in l]
# Wall time: 968 ms
显然使用numpy
模块,更快。
NumPy的核心特征之一就是N-
维数组对象——ndarray
。ndarray
是Python中一个快速、灵活的大型数据集容器。
data = np.random.randn(2, 3)
print(data)
'''
[[-0.7442156 2.04537597 -0.18150464]
[-2.56139122 0.53360941 0.90499989]]
'''
print(data.shape)
print(data.dtype)
'''
(2, 3)
float64
'''
列别表的转换:
In [2]: data1 = [6, 7.4, 7, 2, 0]
In [3]: arr1 = np.array(data1)
In [4]: arr1
Out[4]: array([ 6. , 7.4, 7. , 2. , 0. ])
嵌套序列,例如同等长度的列表,将会自动转换成多维数组:
In [5]: data2 = [[1,2,3,4], [5,6,7,8]]
In [6]: arr2 = np.array(data2)
In [7]: arr2
Out[7]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
dtype
可以用于推断数据类型:
In [8]: arr2.dtype
Out[8]: dtype('int32')
给定长度及形状后,zeros
可以一次性创造全0
数组,ones
可以一次性创造全1
数组。empty
则可以创建一个没有初始化数值的数组。
In [9]: np.zeros(12)
Out[9]: array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [10]: np.zeros((2,4))
Out[10]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
In [12]: np.empty((2,3,2))
Out[12]:
array([[[ 0., 0.],
[ 0., 0.],
[ 0., 0.]],
[[ 0., 0.],
[ 0., 0.],
[ 0., 0.]]])
In [14]: np.arange(12)
Out[14]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
数据类型,即dytpe
:
In [15]: arr1 = np.array([1,2,3], dtype=np.float64)
In [16]: arr1
Out[16]: array([ 1., 2., 3.])
In [17]: arr2 = np.array([3,4,5], dtype=np.int32)
In [18]: arr2
Out[18]: array([3, 4, 5])
可以使用astype
方法显式地转换数组的数据类型:
In [19]: arr = np.array([1,2,3,4,5])
In [21]: arr.dtype
Out[21]: dtype('int32')
In [22]: float_arr = arr.astype(np.float64)
In [23]: float_arr
Out[23]: array([ 1., 2., 3., 4., 5.])
任何在两个等尺寸数组之间的算术操作都应用了逐元素操作的方式:
In [24]: arr = np.array([1,2,3],[4,5,6])
In [25]: arr = np.array([[1,2,3],[4,5,6]])
In [26]: arr
Out[26]:
array([[1, 2, 3],
[4, 5, 6]])
In [27]: arr * arr
Out[27]:
array([[ 1, 4, 9],
[16, 25, 36]])
In [28]: arr - arr
Out[28]:
array([[0, 0, 0],
[0, 0, 0]])
In [29]: 1 / arr
Out[29]:
array([[ 1. , 0.5 , 0.33333333],
[ 0.25 , 0.2 , 0.16666667]])
In [30]: arr
Out[30]:
array([[1, 2, 3],
[4, 5, 6]])
In [31]: 1 / arr
Out[31]:
array([[ 1. , 0.5 , 0.33333333],
[ 0.25 , 0.2 , 0.16666667]])
In [32]: arr ** 0.5
Out[32]:
array([[ 1. , 1.41421356, 1.73205081],
[ 2. , 2.23606798, 2.44948974]])
In [33]: arr2 = ([[3,6,1],[2,6,9]])
In [34]: arr2 > arr1
Out[34]:
array([[ True, True, False],
[ True, True, True]], dtype=bool)
NumPy数组索引有很多种方式可以选中数据的子集或某个单个元素:
In [36]: arr = np.arange(12)
In [37]: arr
Out[37]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [38]: arr[3]
Out[38]: 3
In [39]: arr[6 : 11]
Out[39]: array([ 6, 7, 8, 9, 10])
array的切片操作都是在原数组上进行的。
数组拥有transpose
方法,也有特殊的T
属性:
In [41]: arr = np.arange(15).reshape((3,5))
In [42]: arr
Out[42]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [43]: arr.T
Out[43]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
当计算矩阵内积会使用np.dot
:
In [44]: arr = np.random.randn(6,3)
In [45]: arr
Out[45]:
array([[ 1.0089269 , 0.06504866, -1.63963761],
[ 0.33548612, 0.31657534, 0.55061904],
[ 1.53847939, 1.47153561, 0.86102223],
[-0.51696866, -1.0800848 , 0.46498951],
[-0.5662344 , -0.39992728, -0.81409643],
[-0.41121966, -0.15114092, 0.38753375]])
In [46]: np.dot(arr.T, arr) # 先转置 dot 可以用用于矩阵的相乘
Out[46]:
array([[ 4.25438287, 3.28273789, -0.0836616 ],
[ 3.28273789, 3.61923692, 1.0994601 ],
[-0.0836616 , 1.0994601 , 4.76210275]])