数据分析(NumPy:数组计算)
一、NumPy的特性(数组计算)
- ndarray,一个多维数组结构,高效且节省空间
- 无需循环对整组数据进行快速运算的数学函数
- *读写磁盘数据的工具以及用于操作内存映射文件的工具
- *线性代数、随机数生成和傅里叶变换功能
- *用于集成C、C++等代码的工具
二、安装numpy
# 安装numpy pip install numpy
三、ndarray-多维数组对象
3.1 ndarray是多维数组结构,与列表的区别是:
- 数组对象内的元素类型必须相同
- 数组大小不可修改
3.2 常用属性:
- T 数组的转置(对高维数组而言)
- dtype 数组元素的数据类型
- size 数组元素的个数
- ndim 数组的维数
- shape 数组的维度大小(以元组形式)
# 查看数组维度 arr.ndim # 结果 2 # 数组形状 arr.shape # 结果 (5, 7) # 数组总长度 arr.size # 结果 35 # 数组元素类型 arr.dtype # 结果 dtype('int32') # 查看列表类型 type(arr) #结果 numpy.ndarray
3.3 ndarray-数据类型:
- ndarray数据类型:dtype:
- 布尔型:bool_
- 整型:int_ int8 int16 int32 int64
- 无符号整型:uint8 uint16 uint32 uint64
- 浮点型:float_ float16 float32 float64
- 复数型:complex_ complex64 complex128
四、ndarray-创建:
创建ndarray:
array() 将列表转换为数组,可选择显式指定dtype
arange() range的numpy版,支持浮点数
linspace() 类似arange(),第三个参数为数组长度
zeros() 根据指定形状和dtype创建全0数组
ones() 根据指定形状和dtype创建全1数组
empty() 根据指定形状和dtype创建空数组(随机值)
eye() 根据指定边长和dtype创建单位矩阵
创建数组:array()
import numpy as np # 创建一维数组 arr_1 = np.array([1,2,3,4]) arr_1 # 结果: >>> array([1, 2, 3, 4]) # 创建二维数组 arr_2 = np.array([[1,2,3],[4,5,6]]) arr_2 # 结果 >>> array([[1, 2, 3], [4, 5, 6]]) # 注意: numpy默认ndarray的所有元素的类型是相同的 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str>float>int
使用np的routlines函数创建:
# 等差数列:np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) np.linspace(1, 100, num=20) # 结果 >>>array([ 1. , 6.21052632, 11.42105263, 16.63157895, 21.84210526, 27.05263158, 32.26315789, 37.47368421, 42.68421053, 47.89473684, 53.10526316, 58.31578947, 63.52631579, 68.73684211, 73.94736842, 79.15789474, 84.36842105, 89.57894737, 94.78947368, 100. ]) # np.arange([start, ]stop, [step, ]dtype=None) np.arange(0,100,step=2) # 结果 >>>array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]) # np.random.randint(low, high=None, size=None, dtype='l') np.random.randint(0,100,size=(3,5)) # 3行5列的数组 二维数组 # 结果 >>> array([[35, 13, 69, 58, 55], [43, 63, 65, 87, 44], [46, 72, 28, 81, 43]]) np.random.randint(0,100,size=(2,5,4)) # 三维数组 # 结果 >>>array([[[78, 81, 17, 13], [62, 17, 51, 26], [36, 85, 31, 55], [82, 88, 21, 13], [14, 77, 42, 64]], [[ 2, 87, 62, 36], [ 0, 17, 27, 31], [41, 90, 90, 29], [95, 81, 68, 89], [96, 60, 41, 45]]])
五、ndarray的基本操作(索引,切片,变形,级联)
1、数组和标量之间的运算 a+1 a*3 1//a a**0.5 2、同样大小数组之间的运算 a+b a/b a**b 3、数组的索引: 一维数组:a[5] 多维数组: 列表式写法:a[2][3] 新式写法:a[2,3] (推荐) 数组的切片: 一维数组:a[5:8] a[4:] a[2:10] = 1 多维数组:a[1:2, 3:4] a[:,3:5] a[:,1] 4、强调:与列表不同,数组切片时并不会自动复制,在切片数组上的修改会影响原数组。 【解决方法:copy()】
数据索引:
# 一维数组与列表索引一致,多维数组同理 arr = np.random.randint(0,100,size=(5,7)) arr 结果: >>>array([[51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63], [93, 88, 13, 31, 94, 32, 92], [70, 13, 79, 60, 65, 90, 20], [ 8, 29, 82, 79, 55, 54, 72]]) # 获取前两行 [索引] arr[[0,1]] #结果 >>>array([[51, 63, 81, 46, 35, 25, 11], [93, 88, 13, 31, 94, 32, 92]]) # 获取第二行第三个数 arr[1,2] #结果 55 # 获取第一行数据 arr[1] #结果 array([96, 17, 55, 55, 63, 68, 63])
布尔类型索引:
问题1:给一个数组,选出数组中所有大于5的数。
答案:a[a>5]
原理:
a>5会对a中的每一个元素进行判断,返回一个布尔数组
布尔型索引:将同样大小的布尔数组传进索引,会返回一个由所有True对应位置的元素的数组
问题2:给一个数组,选出数组中所有大于5的偶数。
问题3:给一个数组,选出数组中所有大于5的数和偶数。
答案:
a[(a>5) & (a%2==0)]
a[(a>5) | (a%2==0)]
import numpy as np a = np.array([1,2,3,4,5,4,7,8,9,10]) a[a>5&(a%2==0)] #注意加括号,不叫括号错误,如下 输出:array([ 1, 2, 3, 4, 5, 4, 7, 8, 9, 10]) a[(a>5)&(a%2==0)] 输出:array([ 8, 10])
其他类型索引:
问题1:对于一个数组,选出其第1,3,4,6,7个元素,组成新的二维数组。 答案:a[[1,3,4,6,7]] 问题2:对一个二维数组,选出其第一列和第三列,组成新的二维数组。 答案:a[:,[1,3]]
数组切片:
#一维数组与多维数组与列表的切片方式同理 # 获取二维数组前两行 arr[0:2] #结果: >>>array([[51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63]]) # 获取二位数组前两列 arr[:,0:2] #结果 >>>array([[51, 63], [96, 17], [93, 88], [70, 13], [ 8, 29]]) # 获取二维数组的前两行和前两页 arr[:2,:2] #结果 >>>array([[51, 63], [96, 17]]) # 行倒序 arr[::-1] #j结果 >>>array([[ 8, 29, 82, 79, 55, 54, 72], [70, 13, 79, 60, 65, 90, 20], [93, 88, 13, 31, 94, 32, 92], [96, 17, 55, 55, 63, 68, 63], [51, 63, 81, 46, 35, 25, 11]]) # # 列倒序 arr[:,::-1] #结果 >>>array([[11, 25, 35, 46, 81, 63, 51], [63, 68, 63, 55, 55, 17, 96], [92, 32, 94, 31, 13, 88, 93], [20, 90, 65, 60, 79, 13, 70], [72, 54, 55, 79, 82, 29, 8]]) # 行列都倒序 arr[::-1,::-1] #结果 >>>array([[72, 54, 55, 79, 82, 29, 8], [20, 90, 65, 60, 79, 13, 70], [92, 32, 94, 31, 13, 88, 93], [63, 68, 63, 55, 55, 17, 96], [11, 25, 35, 46, 81, 63, 51]])
数组 变形:
- 使用arr.reshape()函数,注意参数是一个tuple
- 元组中使用参数 -1 可以不用指定维数,
- 相互转换的数据个数必须相同(一维或者多维)
# 创建一个一维数组 arr_1 = np.random.randint(0,100,size=(1,40)) arr_1 #结果 >>>array([[37, 50, 15, 70, 61, 98, 36, 99, 28, 82, 83, 38, 85, 43, 45, 99, 60, 53, 68, 40, 86, 82, 68, 28, 24, 59, 95, 34, 62, 13, 53, 64, 51, 87, 49, 80, 21, 23, 76, 62]]) # 将一维数组变形为多维数组 arr_1.reshape((8,5)) # 结果同上 arr_1.reshape((-1,5)) # -1用法 #结果 >>>array([[37, 50, 15, 70, 61], [98, 36, 99, 28, 82], [83, 38, 85, 43, 45], [99, 60, 53, 68, 40], [86, 82, 68, 28, 24], [59, 95, 34, 62, 13], [53, 64, 51, 87, 49], [80, 21, 23, 76, 62]]) # 将多维数组转换成一维数组 arr.reshape((1,35)) # 数组个数必须相同 #结果 >>>array([[51, 63, 81, 46, 35, 25, 11, 96, 17, 55, 55, 63, 68, 63, 93, 88, 13, 31, 94, 32, 92, 70, 13, 79, 60, 65, 90, 20, 8, 29, 82, 79, 55, 54, 72]])
数组级联:多个numpy数据进行横向或者纵向的拼接
- 数组拼接参数是一个元组tuple
- axis=0表示列,axis=1表示行
print(array) #结果: >>>array([[51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63], [93, 88, 13, 31, 94, 32, 92], [70, 13, 79, 60, 65, 90, 20], [ 8, 29, 82, 79, 55, 54, 72]]) # 列表的列拼接 np.concatenate((arr,arr),axis=0) #结果: array([[51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63], [93, 88, 13, 31, 94, 32, 92], [70, 13, 79, 60, 65, 90, 20], [ 8, 29, 82, 79, 55, 54, 72], [51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63], [93, 88, 13, 31, 94, 32, 92], [70, 13, 79, 60, 65, 90, 20], [ 8, 29, 82, 79, 55, 54, 72]]) # 列表的行拼接 np.concatenate((arr,arr), axis=1) #结果 array([[51, 63, 81, 46, 35, 25, 11, 51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63, 96, 17, 55, 55, 63, 68, 63], [93, 88, 13, 31, 94, 32, 92, 93, 88, 13, 31, 94, 32, 92], [70, 13, 79, 60, 65, 90, 20, 70, 13, 79, 60, 65, 90, 20], [ 8, 29, 82, 79, 55, 54, 72, 8, 29, 82, 79, 55, 54, 72]])
其他常见方法:
array.shape array的规格 array.ndim array.dtype array的数据规格 numpy.zeros(dim1,dim2) 创建dim1*dim2的零矩阵 numpy.arange numpy.eye(n) /numpy.identity(n) 创建n*n单位矩阵 numpy.array([…data…], dtype=float64 ) array.astype(numpy.float64) 更换矩阵的数据形式 array.astype(float) 更换矩阵的数据形式 array * array 矩阵点乘 array[a:b] 切片 array.copy() 得到ndarray的副本,而不是视图 array [a] [b]=array [ a, b ] 两者等价 name=np.array(['bob','joe','will']) res=name==’bob’ res= array([ True, False, False], dtype=bool) data[True,False,…..] 索引,只索取为True的部分,去掉False部分 通过布尔型索引选取数组中的数据,将总是创建数据的副本。 data[ [4,3,0,6] ] 索引,将第4,3,0,6行摘取出来,组成新数组 data[-1]=data[data.__len__()-1] numpy.reshape(a,b) 将a*b的一维数组排列为a*b的形式 array([a,b,c,d],[d,e,f,g]) 返回一维数组,分别为[a,d],[b,e],[c,f],[d,g] array[ [a,b,c,d] ][:,[e,f,g,h] ]=array[ numpy.ix_( [a,b,c,d],[e,f,g,h] ) ] array.T array的转置 numpy.random.randn(a,b) 生成a*b的随机数组 numpy.dot(matrix_1,matrix_2) 矩阵乘法 array.transpose( (1,0,2,etc.) ) 对于高维数组,转置需要一个由轴编号组成的元组
六、ndarray的聚合操作
# 列表中的所有行求和 arr.sum(axis=1) #结果 >>>array([312, 417, 443, 397, 379]) # 列表中的所有列求和 arr.sum(axis=0) #结果 array([318, 210, 310, 271, 312, 269, 258])
其他聚合函数:
其他聚合操作函数: Function Name NaN-safe Version Description np.sum np.nansum Compute sum of elements np.prod np.nanprod Compute product of elements np.mean np.nanmean Compute mean of elements np.std np.nanstd Compute standard deviation np.var np.nanvar Compute variance np.min np.nanmin Find minimum value np.max np.nanmax Find maximum value np.argmin np.nanargmin Find index of minimum value np.argmax np.nanargmax Find index of maximum value np.median np.nanmedian Compute median of elements np.percentile np.nanpercentile Compute rank-based statistics of elements np.any N/A Evaluate whether any elements are true np.all N/A Evaluate whether all elements are true np.power 幂运算
七、ndarray的排序
快速排序:
- np.sort()和nd.array.sort()都可以,但有区别:
- 默认升序
print(array) #结果 >>>array([[51, 63, 81, 46, 35, 25, 11], [96, 17, 55, 55, 63, 68, 63], [93, 88, 13, 31, 94, 32, 92], [70, 13, 79, 60, 65, 90, 20], [ 8, 29, 82, 79, 55, 54, 72]]) # 根据列排序 np.sort(arr, axis=0) #结果: >>>array([[ 8, 13, 13, 31, 35, 25, 11], [51, 17, 55, 46, 55, 32, 20], [70, 29, 79, 55, 63, 54, 63], [93, 63, 81, 60, 65, 68, 72], [96, 88, 82, 79, 94, 90, 92]]) # 根据行排序 np.sort(arr, axis=1) #结果: >>>array([[11, 25, 35, 46, 51, 63, 81], [17, 55, 55, 63, 63, 68, 96], [13, 31, 32, 88, 92, 93, 94], [13, 20, 60, 65, 70, 79, 90], [ 8, 29, 54, 55, 72, 79, 82]])
八、NumPy通用函数
通用函数:能同时对数组中所有元素进行运算的函数
一元函数:abs, sqrt, exp, log, ceil, floor, rint, trunc, modf, isnan, isinf, cos, sin, tan
numpy.sqrt(array) 平方根函数 numpy.exp(array) e^array[i]的数组 numpy.abs/fabs(array) 计算绝对值 numpy.square(array) 计算各元素的平方 等于array**2 numpy.log/log10/log2(array) 计算各元素的各种对数 numpy.sign(array) 计算各元素正负号 numpy.isnan(array) 计算各元素是否为NaN numpy.isinf(array) 计算各元素是否为NaN numpy.cos/cosh/sin/sinh/tan/tanh(array) 三角函数 numpy.modf(array) 将array中值得整数和小数分离,作两个数组返回 numpy.ceil(array) 向上取整,也就是取比这个数大的整数 numpy.floor(array) 向下取整,也就是取比这个数小的整数 numpy.rint(array) 四舍五入 numpy.trunc(array) 向0取整 numpy.cos(array) 正弦值 numpy.sin(array) 余弦值 numpy.tan(array) 正切值
二元函数:add, substract, multiply, divide, power, mod, maximum, mininum,
numpy.add(array1,array2) 元素级加法 numpy.subtract(array1,array2) 元素级减法 numpy.multiply(array1,array2) 元素级乘法 numpy.divide(array1,array2) 元素级除法 array1./array2 numpy.power(array1,array2) 元素级指数 array1.^array2 numpy.maximum/minimum(array1,aray2) 元素级最大值 numpy.fmax/fmin(array1,array2) 元素级最大值,忽略NaN numpy.mod(array1,array2) 元素级求模 numpy.copysign(array1,array2) 将第二个数组中值得符号复制给第一个数组中值 numpy.greater/greater_equal/less/less_equal/equal/not_equal (array1,array2) 元素级比较运算,产生布尔数组 numpy.logical_end/logical_or/logic_xor(array1,array2)元素级的真值逻辑运算
九、浮点数特殊值
- nan(Not a Number):不等于任何浮点数(nan != nan)
- inf(infinity):比任何浮点数都大
在数据分析中,nan常被表示为数据缺失值
既然nan连自己都不相等,那么怎么判断是不是NAN呢?
用a==a 只要返回False就能判断
十、随机数的生成
随机数生成函数在np.random子包内
常用函数
- rand 给定形状产生随机数组(0到1之间的数)
- randint 给定形状产生随机整数
- choice 给定形状产生随机选择
- shuffle 与random.shuffle相同
- uniform 给定形状产生随机数组
https://www.cnblogs.com/WiseAdministrator/