Python 数据分析学习笔记:numpy篇
前言
数据分析的主要库是 pandas,而 numpy 是 pandas 的基础,numpy 中的语法在 pandas 中基本都能使用,所以先学习 numpy。
一.数组的创建
知识点:
- 用赋值法创建 array 数组;
- array 数组的 ndim 属性;
- array 数组的 shape 属性;
- array 数组的 dtype 属性;
- array 数组的 zeros 方法;
- array 数组的 ones 方法;
- array 数组的 arange 方法;
- array 数组的 reshape 方法。
*赋值法是写出数组内容并赋值,注意,多维的 array 中,最外层也要用中括号[ ]括起来
*新创的 array 数组中可以引用已经生成过的 array 数组
*array.ndim 返回 array 的维度值(也称为:秩),dim 是 dimension (英文含义为:维度)的缩写
*(3,3,3)的含义为:3个2维数组,每个2维数组包含3个1维数组,每个1维数组包含3个元素
*arange 有3种效果:
当只有一个参数 n 时,产生一个从0到 n-1 的一维数组(共 n 个数字)
当有两个参数 start, end 时,产生一个从起点数 start 到终点数 end-1 ,步长为 1 的一维数组
当有三个参数 start end num 时,产生一个从起点数 start 到终点数 end-1 ,步长为 num 的一维数组
*注意,这里是 arange ,而不是英文单词 arrange (英文含义:安排),之所以用 arange ,应该是为了和 Python 自带的 range 方法区别开来,但其实两者产生的效果是类似的
*使用 array.reshape(x,y,z) 时,要保证 array 中的元素个数等于 x,y,z 三个数字的积,否则程序会报错,如:2×3×4=24
总结
- numpy 的处理对象主要是 array 数组,array 数组类似于 Python 自带的 list 数组,都使用中括号。
- 生成 array 数组最简单的办法是直接赋值,如 a = np.array([1,2,3])。也可以用已经生成的 array 数组给新的 array 数组赋值。 array 数组可以有任意维度,但是无论多少维度,最外层都要用中括号括起来。
- 除了直接赋值,还有一些生成有特定规律 array 数组的办法:包括生成全 0 数组的 zeros 方法,生成全 1 数组的 ones 方法,生成等差数列的 arange 方法。
- array 数组的主要属性是 ndim, shape, dtype,其中:
* ndim 是数组的维度数,又称秩;
* shape 是数组的型,描述数组在每一个维度上的数量分布,如(2,3,4)代表该数组包括2个二维数组,每个二维数组包括3个一维数组,每个一维数组包括4个数字。如果想改变 array 数组的型,可以用 reshape 方法;
* dtype 是数组的数据类型,下一节会有详述。
二.数据类型与数据类型的转换
知识点:
- array 的主要数据类型;
- 用 reshape 方法转换数据类型;
array 主要数据类型包括:
- 布尔型 bool;
- 整数型 int(包括 int8,int16,int32 等);
- 非负整数型 uint(又称无符号整数,从0开始,包括 uint8 等);
- 浮点数型 float(包括 float16,float32 等);
- 复数型 complex(包括 complex64 和 complex128);
- 字符串型 str
*注意,如果直接输入布尔值,不要加引号(加引号就是 str 型),并要记得将 True 和 False 的首字母大写,否则会报错
*可以使用 astype 方法改变 array 数组的数据类型,注意 astype 的参数需要用引号括起来
*布尔值与数字的对应关系是:True 对应 1,False 对应 0
三.切片索引
知识点:
- 一维数组切片方式;
- 高维数组切片方式;
- 浅复制与深复制。
*一维数组切片有三种方式:
如果仅有一个参数 n(a[n]),则取出数组的第 n + 1 个元素
如果有两个参数 start end(a[start,end]),则取出数组的第 start + 1 个到 end 个间的元素
如果有三个参数 start end step(a[start,end,step]),则以 step 为步长,取出数组的第 start + 1 个到 end 个间的元素
*当 start 省略时,则认为是从第一个元素开始取,当 end 省略时,则认为是取到最后一个元素
*start 和 end 均可以为负数,start 的负数(如 -n)表示为从倒数第 n 个数开始取,而 end 的负数(如 -n)则表示为取到倒数第 n + 1 个数
*步长 num 不能为负值,否则会返回一个空数组
*对于高维数组,继承了一维数组的切片方式,此外,用多个[ ]在不同维度依次切片
*多个[ ]也可以写在一个[ ]中,用逗号连接
*一维数组的表达方式在高维数组中一样适用
*将 array 数组切片并复制给其他数组有两种形式,一种是浅复制,另一种是深复制。在浅复制中,新数组元素的改变会反过来影响原数组,而在深复制中则不会:无论新数组怎么变,都不会影响原数组
*之所以会这样,是出于节约内存的考虑,浅复制不占用新的内存,而深复制会占用新的内存,浅复制后新数组实际上还是用的原数组内存,因此在这种情况下改变新数组元素,就是在改变原数组
*当切片为单一元素时,因为单一元素耗内存较小,所以新数组采用深复制,结果是新数组发生的改变不会影响到原数组
*如果切片不止一个元素,新数组采用浅复制,对新数组元素进行改变,其实就是对原数组改变
*如果不希望采取浅复制,则可以在对新数组复制时采用 copy 方法,这样就是新建内存存储新数组了,这样一来新数组的变化就不会影响到原数组
总结
一维数组切片方式为 array[start: end: step],其中 start 和 end 均能是负数,代表从后往前数,start 和 end 也能省略,代表从第一个开始取和取到最后一个;
一维数组的取数原则是取左不取右;
多维数组继承了一维数组的语法,此外针对高维度用多个[ ]依次切片,多个[ ]也可以写在一个[ ]中,用逗号分隔;
将原数组切片后复制给新数组有两种复制方法,浅复制和深复制,其中浅复制不开启新内存,深复制开启新内存,在浅复制中新数组的改变也就是原数组的改变,而深复制中新数组的改变不影响原数组;
如果原数组只切片出一个元素并复制给新数组,则复制方法为深复制,因为一个元素占内存较小,可以开启新内存;
如果原数组切片出不止一个元素并复制给新数组,则复制方法为浅复制以节约内存,因此新数组的改变也就是原数组的改变;
浅复制情况下如果想改为深复制,可以在复制时使用 copy 方法,这样新数组就拥有独立的内存,它的改变就不会影响原数组了
四.布尔索引
知识点:
- 大于,小于,大于等于,小于等于,整除,非整除等布尔运算的程序表达;
- 或,与,非 等布尔运算的程序表达;
- 一维数组的布尔索引;
- 多维数组的布尔索引
*大于,小于,大于等于,小于等于在 numpy 中的表达为 " > "," < "," >= "," <= "
*" > "," < "," >= "," <= "在 numpy 中是一种运算符,和 " + "," - " 是一样的,用于判断等式是否成立,运算结果是 True 或者 False
*numpy 中的整除、非整除判断要用到两个符号:分别是 " % " 和 " == "(两个等号),其中" % "代表除后取余数," == "相当于数学上的" = ",在程序是一种运算符,判断等式两边是否相等,返回 True 或者 False,而" = "(一个等于号)在 Python 中是赋值符号,不是逻辑判断符号
*numpy 中 "或" 的表达为 " | ",注意,不能用 or 替换 " | "
*"与" 的表达为 " & ","非" 的表达为 " ~ "
*一维数组和高维数组的布尔索引方式一样,都是在数组后加上[ ],并在其中写明布尔运算式
总结
- 所谓布尔运算就是比较布尔运算符前后的元素,看其是否符合布尔运算符代表的含义,并最终输出布尔值(True,False)的运算过程;
- numpy 中的布尔运算符包括:大于( > ),小于( < ),大于等于( >= ),小于等于( <= ), 等于( == ),同时还能用或( | ),与( & ),非( ~ )将多个布尔运算联立;
- numpy 中整除的符号为 % ;
- numpy 中通过布尔运算进行布尔索引,布尔索引的格式和切片索引类似,均是以[ ]为符号,只是布尔索引时[ ]中填入的是布尔运算式;
- numpy 中的高维数组布尔索引和一维数组布尔索引方式没有区别
五.广播与转置
知识点:
- 广播的方法;
- 转置的方法
*所谓广播就是全体数组元素均参与的计算,包括整体广播,按行广播,按列广播(二维数组),按点广播
*整体广播在 array 数组和另一个与之同型(shape)的 array 数组间进行,两个数组间位置对应的元素发生计算
*按点广播是 array 数组的每一个元素均和一个数字标量(如:3,5,29)进行运算
*按行广播是一个二维的 array 数组与一个同行宽的数组进行的运算
*按列广播是一个二维的 array 数组与一个同列长的数组进行的运算
*转置是将原 array 数组的列变成行,行变成列,快捷方式是 T 方法(对应英文单词 transpose,记得大写),同时也可以用 reshape 进行转置
总结
array 数组的整体运算被称为广播(如果不想整体运算,可以先切片索引或布尔索引再运算)
广播的方式包括整体广播(同型广播),按行广播,按列广播,按点广播;
转置是将行变成列,列变成行,快捷方法是 T 方法(对应英文单词 transpose,记得大写),同时也可以用 reshape 实现
六.数组的连接
知识点
- concatenate 方法
- stake 方法
*数组与数组相连接的方法是 concatenate(英文含义:连接),concatenate 中,要连接的数组用元组形式作为方法的第一个参数,第二个参数是 axis ,默认为 0,影响连接方法:针对一维数组,axis 只能为 0,数组按照元组的先后顺序连接(有一点我没有搞清,元组应该是没有先后顺序的)。针对二维数组,axis 为 0 时数组按上下连接,axis 还可以指定为 1,此时数组按左右连接。
*注意,在运用 concatenate 方法时,即使省略 axis 参数(默认为 0),要连接的数组也要用元组的形式(不能省掉元组的括号),否则会报错
*针对二维数组,axis 为 0 时数组按上下连接,axis 还可以指定为 1,此时数组按左右连接。
*用 concatenate 连接时,两个数组可以不同型,但不能创造空值位(如果这里的 a 与 b 纵向相连,a 的第三列将为空值)
*stack 方法也是连接数组的方法,但是和 concatenate 不同,concatenate 不会增加连接后数组的维度,而 stack 会,比如从 1 维升到 2 维,2 维升到 3 维。同时,concatenate 不要求连接的数组一定要同型,但 stake 则要求一定要同型
总结
数组的连接用 concatenate 方法或者 stack 方法,其中 concatenate 方法不会改变数组维度,stack 方法会增加一个数组维度;
对于二维数组而言 concatenate 既可以上下连接(默认),也可以左右连接(要设置 axis = 1 ),对于一维数组,concatenate 只能前后连接;
stack 连接的数组必须同型,concatenate 则不一定(只要不创造空值)
七.随机数
知识点
- np.random.randint();
- np.random.randn();
- np.random.normal();
- np.random.permutation();
- np.random.choice();
- np.save();
- np.load()
*choice 方法中 p(probability,中文意思是:概率)的各项和为 1,否则会报错
总结
np.random.randint(low,high,size):生成 low 与 high 之间的随机整数(取左不取右),size 用于指定要生成数组的型(shape);
np.random.randn(size):生成一个型为 size 的标准正态分布(均值为 0,标准差为 1)数组;
np.random.normal(mean = 0,standard deviation = 1,size):生成一个均值为 mean,标准差为 standard deviation,型为 size 的数组;
np.random.permutation(a):两种模式,如果 a 是一个正整数,则生成一个 0 ~ n-1 的随机排列数组,而如果 a 是一个 array 数组,则生成一个将原 array 元素随机打乱的新数组,其中 permutation 的英文名为:排列;
np.random.choice(array,size = 1,p = none):在数组 array 中按照概率分布 p(列表形式,是英文 probability 的缩写,含义为:概率) 抽取型为 size 的数组;
np.save(file,array):将数组 array 保存为 file,file 包含路径,文件名和文件格式,路径如果省略则为当前 Python 程序运行路径,文件格式如果省略则为 npy 格式(numpy 专属格式)
np.load(file):读取文件中的数据,file包含路径,文件名和文件格式,路径如果省略则为当前 Python 程序运行路径