NumPy
NumPy(Numerical Python)是Python的⼀种开源的数值计算扩展。提供多维数组对象,各种派⽣对象(如掩码数组和矩阵),这种⼯具可⽤来存储和处理⼤型矩阵,⽐Python⾃身的嵌套列表(nested list structure)结构要⾼效的多(该结构也可以⽤来表示矩阵(matrix)),⽀持⼤量的维度数组与矩阵运算,此外也针对数组运算提供⼤量的数学函数库,包括数学、逻辑、形状操作、排序、选择、输⼊输出、离散傅⽴叶变换、基本线性代数,基本统计运算和随机模拟等等。
- ⼏乎所有从事Python⼯作的数据分析师都利⽤NumPy的强⼤功能
- 强⼤的N维数组
- 成熟的⼴播功能
- ⽤于整合C/C++和Fortran代码的⼯具包
- NumPy提供了全⾯的数学功能、随机数⽣成器和线性代数功能
- 只有一个数据类型ndarray,但是同时只能存放一种基本数据类型,下标从0开始
- numpy官方文档
- numpy中文手册
安装使用
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
#pip3 install numpy
#import numpy
创建数组函数
- numpy.empty(shape, dtype=float) : 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组
- numpy.zeros(shape, dtype=float) : 创建指定大小的数组,数组元素以
0
来填充 - numpy.ones(shape, dtype=float) : 创建指定形状的数组,数组元素以
1
来填充
参数描述
- shape : 指定行列数,可以指定多维通过list,tuple的形式均可
- dtype : 数据类型
import numpy as np
# tab 代码提示,再按Tab 就是函数调用
# 在函数的 括号里 shift + tab 可以获得参数提示
#2行3列为0的浮点型数组
print(np.empty([2,3],dtype=float))
#3行3列的空字符串数组
print(np.zeros((3,3),dtype=str))
#3行3列为0的整型数组
print(np.zeros((3,3),dtype=int))
#3行3列为1的整型数组
print(np.ones((3,3),dtype=int))
#3行3列为1的整型数组 类型可以以字符串形式传递
print(np.ones((3,3),dtype='int64'))
结果输出
[[6.89798700e-307 2.00267682e-307 2.78150360e-307]
[4.00541815e-307 2.78148492e-307 1.76128176e-312]]
[['' '' '']
['' '' '']
['' '' '']]
[[0 0 0]
[0 0 0]
[0 0 0]]
[[1 1 1]
[1 1 1]
[1 1 1]]
[[1 1 1]
[1 1 1]
[1 1 1]]
用已有数据创建数组
- numpy.asarray(object, dtype = None) : 将结构数据转换成ndarray数组,当数据源是ndarray时,为浅拷贝(原数据变化后,新数组也变化)
- numpy.array(object, dtype = None) : 将结构数据转换成ndarray数组,当数据源是ndarray时,为深拷贝(原数据变化后,新数组不变化)
#利用列表进行创建数组
l1 = [1,2,3,4]
print(np.asarray(l1,dtype=str))
l2=[(1,2,3),(4,5,6),(7,8,9)]
print(np.asarray(l2))
l3=[5, 6, 7, 8]
print(np.array(l3,dtype=float))
#利用元组创建数组
t1 =(1,2,3,4)
print(np.array(t1))
t2 =((1,2,3),(3,4,5))
print(np.array(t2))
# 验证np.array 与 np.asarray 的区别,np.asarray为浅拷贝
arr1 = np.ones((3,3),dtype=int)
asarr = np.asarray(arr1)
ar_arr1 = np.array(arr1)
arr1[1] =2
print(arr1)
print(asarr)
print(ar_arr1)
结果输出
#利用列表进行创建数组
['1' '2' '3' '4']
[[1 2 3]
[4 5 6]
[7 8 9]]
[5. 6. 7. 8.]
#利用元组创建数组
[1 2 3 4]
[[1 2 3]
[3 4 5]]
# 验证np.array 与 np.asarray 的区别,np.asarray为浅拷贝
[[1 1 1]
[2 2 2]
[1 1 1]]
[[1 1 1]
[2 2 2]
[1 1 1]]
[[1 1 1]
[1 1 1]
[1 1 1]]
从数值范围创建数组
- numpy.arange(start, stop, step, dtype)
参数描述
- start : 起始值,默认为0
- stop : 终止值(不包含)
- step : 步长,默认为1
- dtype : 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型
#创建10到100 并且步长为10的数组(同切片一样包含开始,不包含结束)
arr1 = np.arange(10,100,10)
print(arr1)
# 结果
[10 20 30 40 50 60 70 80 90]
- np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数描述
- start : 序列的起始值
- stop : 序列的终止值,如果endpoint为
true
,该值包含于数列中 - num : 要生成的等步长的样本数量,默认为50
- endpoint : 该值为
true
时,数列中包含stop值,反之不包含,默认是True
- retstep : 如果为
True
时,生成的数组中会显示间距,反之不显示。 - dtype : ndarray的数据类型
#指定区间均匀分割创建数组
arr2 = np.linspace(10,100,10,endpoint=True,dtype=int)
print(arr2)
# 结果
[ 10 20 30 40 50 60 70 80 90 100]
利用随机函数创建数组
- numpy.random.rand(dn) : 0-1之间均匀分布的浮点数
- numpy.random.randn(dn) : 标准正态分布(均值为0,标准差为1)
- numpy.random.randint(low,high,size) : 依据形状用low~high区间的数值创建数组
- numpy.random.uniform(low,high, size) : 产生均匀分布的数组,起始值为low,high为结束值,size为形状
- numpy.random.normal(loc, scale, size) : 产生正态分布的数组,loc为均值,scale为标准差,size为形状
#创建2行3列的0-1之间均匀分布浮点数
arr1 = np.random.rand(2,3)
print("0-1间均匀分布\n",arr1)
#创建3行3列的标准正态分布的浮点数
arr2 = np.random.randn(3,3)
print("正态分布\n",arr2)
#创建3,3列10-100之间的整数
arr3 = np.random.randint(10,100,(3,3))
print("10-100整数\n",arr3)
#创建3,3列10-100之间的浮点数
arr4 = np.random.uniform(10,100,(3,3))
print("10-100浮点数\n",arr4)
#创建3,3列正定均值,标准差的正态分布
arr5 = np.random.normal(80,10,(3,3))
print("均值为80,标准差为10的浮点数\n",arr5)
输出结果
#0-1间均匀分布
[[0.29497593 0.83171348 0.43229655]
[0.28426801 0.90516017 0.38341161]]
#正态分布
[[-1.04862542 -1.29375091 0.92648632]
[-1.55675552 0.8527372 -0.48236677]
[-0.48029127 2.03284023 -0.93163757]]
#10-100整数
[[39 47 93]
[68 33 75]
[96 20 46]]
#10-100浮点数
[[89.10309942 88.02850559 22.2223232 ]
[83.32027834 56.53886041 24.20109113]
[35.01408475 42.69099473 95.07580552]]
#均值为80,标准差为10的浮点数
[[80.09020601 89.21345912 68.49795065]
[67.0012265 75.19606176 73.8063407 ]
[87.48909856 71.63283437 83.96595267]]
数组属性
- arr.dtype : 元素类型
- arr.ndim : 数组维度
- arr.shape : 数组形状
- arr.size : 元素个数
arr1 = np.array([[1,2,3],[4,5,6]])
print("dtype",arr1.dtype) # int32
print("ndim",arr1.ndim) # 2
print("shape",arr1.shape) # (2, 3)
print("size",arr1.size) # 6
修改数组维度
- arr.reshape(shape, order='C') : 返回改变维度后的数组
- arr.resize(shape) : 改变当前数组维度
- numpy.ravel(array,order="C") : 返回改变维度后的一维数组
参数描述
- shape : 指定行列数,可以指定多维通过list,tuple的形式均可
- order :
C
按行,F
按列,A
原顺序
区别
- resize 无返回值(返回值为None),会改变原数组。
- reshape 有返回值,返回值是被reshape后的数组,不会改变原数组。
- resize 可以放大或者缩小原数组的形状:放大时,会用0补全剩余元素;缩小时,直接丢弃多余元素。
- reshape 要求reshape前后元素个数相同,否则会报错,无法运行。
#5行4列的数组转换为10行2列的数组(要想改变元数组要重新赋值)
arr = np.random.normal(80,5,(5,4))
print(arr.reshape([10,2]))
arr.resize([4,5])
print(arr)
输出结果
[[74.50410143 79.85385333]
[69.01923402 75.68557736]
[73.10327129 75.23198585]
[79.08259875 77.0005062 ]
[86.10986076 87.40839827]
[80.69638411 83.56963886]
[81.7102163 87.87354462]
[81.34607894 82.97543228]
[75.38878448 75.71512295]
[75.78989293 77.78025783]]
[[74.50410143 79.85385333 69.01923402 75.68557736 73.10327129]
[75.23198585 79.08259875 77.0005062 86.10986076 87.40839827]
[80.69638411 83.56963886 81.7102163 87.87354462 81.34607894]
[82.97543228 75.38878448 75.71512295 75.78989293 77.78025783]]
数组访问与修改
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样[开始:结束:步长].ndarray 数组可以基于
0-n
的下标进行索引
- 一维数组
arr = np.arange(1,11)
print("arr\n",arr)
print("arr[::2]\n",arr[::2])
print("arr[1::2]\n",arr[1::2])
print("arr[:5]\n",arr[:5])
print("arr[5:]\n",arr[5:])
输出结果
arr
[ 1 2 3 4 5 6 7 8 9 10]
arr[::2]
[1 3 5 7 9]
arr[1::2]
[ 2 4 6 8 10]
arr[:5]
[1 2 3 4 5]
arr[5:]
[ 6 7 8 9 10]
- 二维数组
#二维数组
arr=np.random.randint(1,100,(3,4))
print("arr\n",arr)
#通过行索引访问行
print("arr[0]\n",arr[0])
#对行索引进行切片
print("arr[:2]\n",arr[:2])
#对行和列进行切片
print("arr[:2,2:]\n",arr[:2,2:])
输出结果
arr
[[95 23 83 92]
[93 60 22 64]
[70 4 8 31]]
arr[0]
[95 23 83 92]
arr[:2]
[[95 23 83 92]
[93 60 22 64]]
arr[:2,2:]
[[83 92]
[22 64]]
数组切片访问与修改
- slice(stop) : 切片函数,等价于
:结束
- slice(start,stop ,step) : 等价于
开始:结束:步长
参数描述
- start : 开始标记,包含
- stop : 结束标记,不包含
- step : 步长
ar = np.arange(1,13).reshape([3,4])
print(ar)
print(ar[:2])
print(ar[slice(2)])
print(ar[:,::2])
print(ar[slice(3),slice(0,4,2)])
#取1,3行
print(ar[np.arange(0,3,2)])
输出结果
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[1 2 3 4]
[5 6 7 8]]
[[1 2 3 4]
[5 6 7 8]]
[[ 1 3]
[ 5 7]
[ 9 11]]
[[ 1 3]
[ 5 7]
[ 9 11]]
[[ 1 2 3 4]
[ 9 10 11 12]]
利用True,False进行访问与修改
通过相等形状的元素为True,False的数组对数据进行获取,通过对数组进行判断的形式得到相同形状的True,False数组
#大于10的数
ar = np.arange(1,21).reshape((4,5))
print(ar)
# 5的倍数
print(ar[ar % 5==0])
# 奇数
print(ar[ar % 2==1])
# 偶数
print(ar[ar % 2==0])
输出结果
[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]]
[ 5 10 15 20]
[ 1 3 5 7 9 11 13 15 17 19]
[ 2 4 6 8 10 12 14 16 18 20]
算数函数
- numpy.add(arr1,arr2或常数) : 数组+常数,相同shape或相同行或相同列数组相加
- numpy.substract(arr1,arr2或常数) : 数组-常数,相同shape或相同行或相同列 数组相减
- numpy.multiply(arr1,arr2或常数) : 数组*常数,相同shape或相同行或相同列 数组相乘
- numpy.divide(arr1,arr2或常数) : 数组/常数,相同shape或相同行或相同列数组相除
- numpy.exp(arr) : e
**
arr - numpy.power(arr1,arr2或常数) : 等价于
**
- numpy.mod(arr1,arr2或常数) : 数组%常数,相同shape或相同行或相同列数组取余
- numpy.modf(arr) : 分开整数部分和小数部分
- numpy.log(arr) : ln,表示e的多少次方为此数组的元素值
- numpy.log2(arr) : log以2为底的对数
- numpy.log10(arr) : log以10位底的对数
- numpy.sqrt(arr) : 对数组进行开方
- numpy.square(arr) : 当前数组二次幂
- numpy.around(arr,小数点位数) : 4舍5入后保留指定位数的小数点
- numpy.floor(arr) : 向下取整
- numpy.ceil(arr) : 向上取整
- numpy.sign(arr) : 取符号,正数为1,0,负数为-1
字符串函数
- numpy.char.add(arr_str,arr2或常数) : 不能用+号代替
- numpy.char.multiply(arr_str,arr2或常数) : arr2或常数 是整数(重复字符串次数)
- numpy.char.center(arr_str,长度,fillchar="不够长度填充字符") : 将字符串居中,并使用指定字符在左侧和右侧进行填充
- numpy.char.capitalize(arr_str) : 首字母大写
- numpy.char.strip(arr_str) : 去掉左右两侧空格
- numpy.char.lstrip(arr_str) : 去掉左空格
- numpy.char.rstrip(arr_str) : 去掉右空格
- numpy.char.lower(arr_str) : 所有字母变小写
- numpy.char.upper(arr_str) : 所有字母变大写
- numpy.char.split(arr_str,sep=分隔符) : 按指定分隔符分割
- numpy.char.replace(arr_str,old="要替换掉的字符","新字符") : 指定字符替换
list1 = [["lili","Jim","Tom","son"],[" bijing","shang hai","tian jin","shen zhen "]]
ar = np.array(list1)
np.char.replace(ar[1],"I","i")
print(np.char.split(ar[1],sep=" "))
print(np.char.split(ar[0,1]))
ar = np.char.upper(ar)
print(ar)
print(np.char.lower(ar))
ar = np.char.lstrip(ar)
print(ar)
print(np.char.capitalize(ar))
print(np.char.center(ar[0],10,fillchar="*"))
print(np.char.multiply(ar[0],np.asarray([2,3,4,5])))
print(np.char.add(ar[0],"_name"))
结果输出
[list(['', 'bijing']) list(['shang', 'hai']) list(['tian', 'jin'])
list(['shen', 'zhen', '', '', ''])]
['Jim']
[['LILI' 'JIM' 'TOM' 'SON']
[' BIJING' 'SHANG HAI' 'TIAN JIN' 'SHEN ZHEN ']]
[['lili' 'jim' 'tom' 'son']
[' bijing' 'shang hai' 'tian jin' 'shen zhen ']]
[['LILI' 'JIM' 'TOM' 'SON']
['BIJING' 'SHANG HAI' 'TIAN JIN' 'SHEN ZHEN ']]
[['Lili' 'Jim' 'Tom' 'Son']
['Bijing' 'Shang hai' 'Tian jin' 'Shen zhen ']]
['***LILI***' '***JIM****' '***TOM****' '***SON****']
['LILILILI' 'JIMJIMJIM' 'TOMTOMTOMTOM' 'SONSONSONSONSON']
['LILI_name' 'JIM_name' 'TOM_name' 'SON_name']
统计函数
集中趋势
- numpy.mean() : 统计数组元素的平均值
- numpy.median(arr) : 统计数组元素的中位数
- numpy.percentile(arr,q=[0-100 的数表示百分位点]) : 沿指定轴计算数据a的第q百分位
ar = np.random.randint(1,10,4)
print(np.mean(ar))
print(np.median(ar))
print(np.percentile(ar,q=[25,50,75]))
输出结果
5.5
5.0
[4.5 5. 6. ]
离散程度
- np.var(arr) : 方差
- arr1.std() : 标准差
- arr1.ptp() : 极差
ar = np.random.randint(1,10,4)
print(np.var(ar),np.std(ar),np.ptp(ar))
per =np.percentile(ar,[25,75])
# 四分位差
IQR = per[1] - per[0]
print(IQR)
#离散系数 σ/μ 标准差除以均值 作用:比较不同数据源的离散程度
v = np.std(ar) /np.mean(ar)
print(v)
输出结果
0.1875 0.4330127018922193 1
0.25
0.07530655685082074
- numpy.diff() : 沿着指定轴计算第N维的离散差值
ar = np.random.randint(1,10,4)
ar2=np.diff(ar)
print(ar2)
np.diff(ar,n=2) # 一阶基础上进行2阶差分
np.diff(ar2,n=1)
输出结果
[-2, -3, 0]
[-1, 3]
分布形态
- arr.max() : 寻找最大值
- arr.argmax() : 返回最大值的索引
- arr.min() : 寻找最小值
- arr.argmin() : 返回最小值的索引
- arr.sum() : 指定维度的元素进行求和
ar = np.random.randint(10,100,(3,4))
print(np.max(ar),np.min(ar),np.argmax(ar),np.argmin(ar),np.sum(ar))
#第一行中最大的数所对应的,2,3行的数
ar[1:,ar[0] == np.max(ar[0])]
输出结果
93 19 6 9 702
array([[70],[19]])
- numpy.sort(arr,axis) : 排序(更改原数组)
- numpy.diff(arr,n,axis) : 差分
- numpy.where(条件,True_value,False_Value) : 满足条件,返回True_value,否则返回 False_value
- numpy.where(条件) : 返回符合条件的下标
参数描述
- axis : 维0代表行,1代表列
- n : 阶数
ar = np.random.randint(10,50,10)
ar = np.sort(ar)
print(ar[::-1])
print(np.diff(ar))
print(np.where(ar>40,1,0))
print(np.where(ar>20))
输出结果
[46 44 40 40 34 31 21 18 16 12]
[ 4 2 3 10 3 6 0 4 2]
[0 0 0 0 0 0 0 0 1 1]
(array([3, 4, 5, 6, 7, 8, 9], dtype=int64),)
文件IO操作
保存数组
- np.save("文件名.npy",数组) : 保存ndarray到⼀个npy⽂件
- np.savez("文件名.npz",key1 = 数组1,key2=数组2....) : 将多个array保存到⼀个.npz⽂件中
ar = np.random.randint(10,100,(3,4))
ar1 = np.random.randint(10,100,(3,4))
np.save("ar.npy",ar)
np.savez("d_ar.npz",one=ar,two=ar1)
读取数组
- np.load(文件名.npy或.npz) : 读取存储的数组,如果是.npz⽂件的话,读取之后相当于形成了⼀个key-value类型的变量,np.load(文件名.npz).files 获得文件Key
f1 = np.load("ar.npy")
f2 = np.load("d_ar.npz")
print(f1,f2.files)
输出结果
[[80 95 46 18]
[76 44 84 45]
[33 82 92 55]] ['one', 'two']
读写csv、txt⽂件
- numpy.savetxt("文件名.csv 或者 txt,数组,delimiter="元素分隔符") : 保存数组为csv、txt文件
- numpy.loadtxt("文件名.csv 或者 txt,delimiter="元素分隔符") : 读取数组csv、txt文件
ar = np.random.randint(10,100,(3,4))
np.savetxt("test.csv",ar,delimiter=',')
np.loadtxt("test.csv",delimiter=",")
输出结果
array([[30., 30., 90., 59.],
[18., 35., 78., 44.],
[49., 36., 10., 63.]])
最后一次更新于2023-06-09 16:52
0 条评论