阅读SeanCheney博主上传的文章有感,特此写一篇笔记,如侵必删。
第四章 NumPy基础
NumPy的ndarray:一种多维数组对象
1. 创建ndarray
array函数,接受序列性的对象,如列表data1 = [6, 7.5, 8, 0, 1]arr1 = np.array(data1) #一维数组data2 = [[1, 2, 3, 4], [5, 6, 7, 8]] #每一行用一个方括号arr2 = np.array(data2) #二维数组
特殊数组
np.zeros(10)np.zeros((3, 6))np.ones #创建全1数组np.eye #创建单位阵np.arange(15)Out[32]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])points = np.arange(-5, 5, 0.01)
随机数组
data = np.random.randn(2, 3) #两行三列
2. 数据类型
没有特别指定,创建的数组,数据类型都是float64(浮点数)
arr2.shape
查看数组的大小
arr1.dtype
查看数组的数据类型
创建一个指定数据类型的数组:arr1 = np.array([1, 2, 3], dtype=np.float64)
数据类型转换常见的数据类型有:(u)int8、(u)int16、(u)int32、(u)int64、float16、float32、float64、bool…
float_arr = arr.astype(np.float64)
该功能强大的地方在于,可以直接将字符串转换为数值形式:numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
3. 数组运算
算术运算:加、减、乘、除、乘方(**)关系运算:> 、<4. 切片和索引
切片基本功能与Python相似
关注切片的赋值,NumPy的数组切片相当于引用,更改了切片,同样更改了原数组
arr = np.arange(10)arr[5:8] = 12 #给切片赋值,相当于所有元素都赋值Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])arr_slice = arr[5:8]arr_sliceOut[67]: array([12, 12, 12])arr_slice[1] = 12345arrOut[69]: array([0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
这种操作,是考虑了性能和内存,如果要复制切片,使用copy函数:arr[5:8].copy()
索引 一维:arr2d[0]
二维:arr2d[0][2]
和arr2d[0, 2]
二维访问行:arr2d[0]
切片索引:arr2d[:2]
表示前两行,arr2d[:2, 1:]
前两行中的后两列布尔索引
In [98]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])In [99]: data = np.random.randn(7, 4)In [100]: namesOut[100]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],dtype='<U4')In [101]: dataOut[101]: array([[ 0.0929, 0.2817, 0.769 , 1.2464],[ 1.0072, -1.2962, 0.275 , 0.2289],[ 1.3529, 0.8864, -2.0016, -0.3718],[ 1.669 , -0.4386, -0.5397, 0.477 ],[ 3.2489, -1.0212, -0.5771, 0.1241],[ 0.3026, 0.5238, 0.0009, 1.3438],[-0.7135, -0.8312, -2.3702, -1.8608]])#下面进行布尔索引In [102]: names == 'Bob'Out[102]: array([ True, False, False, True, False, False, False], dtype=bool)#相当于直接将一系列bool值当做数组的索引In [103]: data[names == 'Bob']Out[103]: array([[ 0.0929, 0.2817, 0.769 , 1.2464],[ 1.669 , -0.4386, -0.5397, 0.477 ]])#布尔索引行,添加列索引In [104]: data[names == 'Bob', 2:]Out[104]: array([[ 0.769 , 1.2464],[-0.5397, 0.477 ]])In [105]: data[names == 'Bob', 3]Out[105]: array([ 1.2464, 0.477 ])#利用逻辑运算进行bool索引In [110]: mask = (names == 'Bob') | (names == 'Will')In [111]: maskOut[111]: array([ True, False, True, True, True, False, False], dtype=bool)In [112]: data[mask]Out[112]: array([[ 0.0929, 0.2817, 0.769 , 1.2464],[ 1.3529, 0.8864, -2.0016, -0.3718],[ 1.669 , -0.4386, -0.5397, 0.477 ],[ 3.2489, -1.0212, -0.5771, 0.1241]])
花式索引注意:Python关键字and和or在布尔型数组中无效。要使用&与|。
可以按照一定的顺序进行索引数组的每一行,格式arr[[4, 3, 0, 6]]
In [120]: arr[[4, 3, 0, 6]] #索引顺序为第4,3,0,6行Out[120]: array([[ 4., 4., 4., 4.],[ 3., 3., 3., 3.],[ 0., 0., 0., 0.],[ 6., 6., 6., 6.]])
花式索引跟切片不一样,它总是将数据复制到新数组中。
5. 转置和轴对换
转置:arr.T
内积:np.dot(arr.T, arr)
通用函数:快速的元素级数组函数
1. 一元函数
np.sqrt(arr)
np.exp(arr)
sin、cos、sinh、cosh、tan、tanh
2. 二元函数
np.maximum(x, y)
返回对应x与y中最大的元素remainder, whole_part = np.modf(arr)
分别返回浮点数的小数部分、整数部分利用数组进行数据处理
1. 网格数组计算距离
网格点首先介绍一下np.meshgrid
这个函数,引用自博主千千Sama的文章,生成网格点坐标矩阵。假如x坐标已经已知范围,y坐标也已经已知范围,那么这个函数相当于对x坐标和y坐标进行排列组合,生成坐标点的横坐标和纵坐标。该函数的输出是两个值,分别是对应的坐标点的x坐标和y坐标,形式上看,就是x坐标范围复制成每一行,y坐标复制成每一列。求距离
z = np.sqrt(xs ** 2 + ys ** 2)
,直接对两个数组进行求解,如果利用Python逻辑,还得需要循环求解。
2. 将条件逻辑表述为数组运算
np.where
函数的使用,有三个输入参数,第一个参数是条件表达式,第二、三个参数分别是条件成立后的值和不成立的值。
step = 1 if random.randint(0, 1) else -1
这种表达方式类似于np.where
,都是条件跟结果。
可以想到,该函数可以按照条件对数组的部分值进行筛选和替换
In [165]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])In [166]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])In [167]: cond = np.array([True, False, True, True, False])In [170]: result = np.where(cond, xarr, yarr) #条件表示为1In [171]: resultOut[171]: array([ 1.1, 2.2, 1.3, 1.4, 2.5])arr = np.random.randn(4, 4)In [173]: arrOut[173]: array([[-0.5031, -0.6223, -0.9212, -0.7262],[ 0.2229, 0.0513, -1.1577, 0.8167],[ 0.4336, 1.0107, 1.8249, -0.9975],[ 0.8506, -0.1316, 0.9124, 0.1882]])In [175]: np.where(arr > 0, 2, -2) #条件表示正数Out[175]: array([[-2, -2, -2, -2],[ 2, 2, -2, 2],[ 2, 2, 2, -2],[ 2, -2, 2, 2]])
3. 统计函数
arr.mean()
arr.sum(axis=0)
#计算每列的和,1是列轴向
arr.min()
和arr.max()
arr.std()
和arr.var()
#分别是标准差和方差
4. 布尔操作
统计数组满足条件的个数:(arr > 0).sum()
统计数组内正数元素的个数测试布尔型数组True的个数:bools.any()
测试数组中是否存在一个或多个True。bools.all()
检查数组中所有值是否都是True。其实第二个操作可以用第一种方法来测试。
5. 排序
arr.sort()
默认从小到大arr.sort(1)
按照行从小到大排序,其实默认就是按照行进行排序以上方法会改变数组本身,而采用np.sort
能够返回数组的已排序的副本,不管是mean函数,还是sort函数,如果不想改变原来的数组,需要采用np.mean这种形式
6. 唯一化
其实就是去除数组中的重复值,在Python逻辑中,首先想到的就是强制转换为集合set类型,但在NmuPy中可以采用函数来处理。
np.unique(names)
去掉重复值,并且排序sorted(set(names))
在Python中需要进行类型转换并且排序
用于数组的文件输入与输出
1.np.save
二进制形式保存在.py文件中
In [213]: arr = np.arange(10)In [214]: np.save('some_array', arr) #扩展名会自动加上
2.np.load
读取磁盘上的数据
In [215]: np.load('some_array.npy')Out[215]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
3.np.savez
多个数组保存
In [216]: np.savez('array_archive.npz', a=arr, b=arr)In [217]: arch = np.load('array_archive.npz')In [218]: arch['b']Out[218]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
4.numpy.savez_compressed
数据压缩
In [219]: np.savez_compressed('arrays_compressed.npz', a=arr, b=arr)
线性代数
1. 点积x.dot(y)
和np.dot(x, y)
2. 行列式np.det
伪随机数
samples = np.random.normal(size=(4, 4))
得到一个标准正态分布的4x4样本
np.random.seed(1234)
更改随机数种子
如果觉得《《利用Python进行数据分析》笔记--NumPy数组和矢量计算》对你有帮助,请点赞、收藏,并留下你的观点哦!