1 NumPy ndarray简介
是NumPython的一个N维数组对象,一个面向同质数据的高效、稳定的大数据集通用容器。
同质数据特征为,每个数组:
<1>都有一个 shape属性(数组的维度分布描述)
<2>一个元组用以索引(indicating)每个维度的大小
<3>一个 dtype属性,也即容器中数据类型,int8\int16\...
2 使用
2.1 创建ndarray 使用 array函数
In [13]: data1 = [6, 7.5, 8, 0, 1]
In [14]: arr1 = np.array(data1)
In [15]: arr1 Out[15]: array([ 6. , 7.5, 8. , 0. , 1. ])
创建0元素数组和1元素数组
In [23]: np.zeros(10)
Out[23]: array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [24]: np.zeros((3, 6))
Out[24]
array([[ 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.]])
In [25]: np.empty((2, 3, 2))
Out[25]: array([[[ 4.94065646e-324, 4.94065646e-324],
[ 3.87491056e-297, 2.46845796e-130],
[ 4.94065646e-324, 4.94065646e-324]],
[[ 1.90723115e+083, 5.73293533e-053],
[ -2.33568637e+124, -6.70608105e-012],
[ 4.42786966e+160, 1.27100354e+025]]])
创建序列数组 arange (个人理解是:arange=array+range)
In [26]: np.arange(15)
Out[26]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
可以直接转换数组的数据类型
In [31]: arr = np.array([1, 2, 3, 4, 5])
In [32]: arr.dtype Out[32]: dtype('int64')
In [33]: float_arr = arr.astype(np.float64)
In [34]: float_arr.dtype Out[34]: dtype('float64')
2.2 数组array的操作
数组的操作结果可以直接反应到数组中每个元素上
In [45]: arr = np.array([[1., 2., 3.], [4., 5., 6.]])
In [46]: arr Out[46]: array([[ 1., 2., 3.],
[ 4., 5., 6.]])
In [47]: arr * arr
Out[47]: array([[ 1., 4., 9.],
[ 16., 25., 36.]])
2.3 数组的分割和索引
一维数组:
In [51]: arr = np.arange(10)
In [52]: arr Out[52]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [54]: arr[5:8]
Out[54]: array([5, 6, 7])
In [55]: arr[5:8] = 12
In [56]: arr
Out[56]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
多维数组:
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
取值:
In [68]: arr3d[0]
Out[68]: array([[1, 2, 3],
[4, 5, 6]])
arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
In [78]: arr2d[:2, 1:]
Out[78]: array([[2, 3],
[5, 6]])
2.4 boolean 索引
注意:boolean 数组长度必须与其索引的数组长度一致
In [83]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
In [84]: data = numpy.random.randn(7, 4)
In [85]: names
Out[85]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='|S4')
In [86]: data
Out[86]: array([[-0.048 , 0.5433, -0.2349, 1.2792],
[-0.268 , 0.5465, 0.0939, -2.0445],
[-0.047 , -2.026 , 0.7719, 0.3103],
[ 2.1452, 0.8799, -0.0523, 0.0672],
[-1.0023, -0.1698, 1.1503, 1.7289],
...........
假若我们想选择 name='Bob'的data数组
In [87]: names == 'Bob'
Out[87]: array([ True, False, False, True, False, False, False], dtype=bool
In [88]: data[names == 'Bob']
Out[88]: array([[-0.048 , 0.5433, -0.2349, 1.2792], [ 2.1452, 0.8799, -0.0523, 0.0672]])
如果想选择除了name='Bob'以外其他所有,可以使用 (1)“ !=” 不等于号 (2) 负号“-”
In [91]: names != 'Bob'
Out[91]: array([False, True, True, False, True, True, True], dtype=bool)
In [92]: data[-(names == 'Bob')]
Out[92]: array([[-0.268 , 0.5465, 0.0939, -2.0445],
[-0.047 , -2.026 , 0.7719, 0.3103],
[-1.0023, -0.1698, 1.1503, 1.7289],
[ 0.1913, 0.4544, 0.4519, 0.5535],
[ 0.5994, 0.8174, -0.9297, -1.2564]])
使用多条件 ,就要使用python逻辑运算负号 "&"和"|"
In [93]: mask = (names == 'Bob') | (names == 'Will')
In [94]: mask
Out[94]: array([True, False, True, True, True, False, False], dtype=bool)
In [95]: data[mask]
Out[95]: array([[-0.048 , 0.5433, -0.2349, 1.2792],
[-0.047 , -2.026 , 0.7719, 0.3103],
[ 2.1452, 0.8799, -0.0523, 0.0672],
[-1.0023, -0.1698, 1.1503, 1.7289]])
2.5 混合(fancy) 索引
In [100]: arr = np.empty((8, 4))
In [101]: for i in range(8):
arr[i] = i
In [102]: arr
Out[102]: array([[ 0., 0., 0., 0.],
[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.],
[ 3., 3., 3.,3.],
[ 4., 4., 4., 4.],
[ 5., 5., 5., 5.],
[ 6., 6., 6., 6.],
[ 7., 7., 7., 7.]])
如果我们想选择其中几行:
In [103]: arr[[4, 3, 0, 6]]
Out[103]: array([[ 4., 4., 4., 4.],
[ 3., 3., 3., 3.],
[ 0., 0., 0., 0.],
[ 6., 6., 6., 6.]])
如果arr[list] 中list里有负数,代表从数组尾部开始往头选择
In [104]: arr[[-3, -5, -7]]
Out[104]: array([[ 5., 5., 5., 5.],
[ 3., 3., 3., 3.],
[ 1., 1., 1., 1.]])
对二维数组的元素逐个选择的特殊方式:
In [107]: arr[[1, 5, 7, 2], [0, 3, 1, 2]]
Out[107]: array([ 4, 23, 29, 10])
(解读:arr[[1, 5, 7, 2], [0, 3, 1, 2]] 分别对应组合成:(1,0),(5,3),(7,1),(2,2) 分别是行和列 的对,即从数组中选择了4个元素)
如果想在获取其中几行的同时转换列的顺序,如下方式(注意与上面的区别):
<pre class="python" name="code">In [108]: arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
Out[108]: array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])
2.6 数组转换和 轴的转置 (‘T’属性,transpose方法,swapaxes方法)
先生成一个随机矩阵(reshape可以控制数组的行列)
In [115]: arr = np.arange(16).reshape((2, 2, 4))
In [116]: arr
Out[116]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
#数据的行列变换
In [117]: arr.transpose((1, 0, 2))
Out[117]: array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
# 'T' 属性仅仅是轴变换的一个特例,使用轴变换方法,swapaxes
In [119]: arr.swapaxes(1, 2)
Out[118]:
array([[
[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]],
[[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])
2.7 通用函数:快速逐元素函数
#求平方根和指数函数
In [120]: arr = np.arange(10)
In [121]: np.sqrt(arr)
Out[121]: array([ 0. , 1. , 1.4142, 1.7321, 2. , 2.2361, 2.4495, 2.6458, 2.8284, 3. ])
In [122]: np.exp(arr)
Out[122]: array([ 1. , 2.7183, 7.3891, 20.0855, 54.5982, 148.4132, 403.4288, 1096.6332, 2980.958 , 8103.0839])
注意下面的求最大数和最小数,也可以直接在两个数组中进行。(两两对中的最大、最小数)
In [123]: x = randn(8)
In [124]: y = randn(8)
In [125]: x
Out[125]: array([ 0.0749, 0.0974, 0.2002, -0.2551, 0.4655, 0.9222, 0.446 , -0.9337])
In [126]: y
Out[126]: array([ 0.267 , -1.1131, -0.3361, 0.6117, -1.2323, 0.4788, 0.4315, -0.7147])
In [127]: np.maximum(x, y)
Out[127]: array([ 0.267 , 0.0974, 0.2002, 0.6117, 0.4655, 0.9222, 0.446 , -0.7147])