一、ndarray概念
1、回顾python基本类型
数字类型: 整型: 布尔型bool、整型int、长整形long非整型:浮点float 、复数complex
容器: 序列:字符串str 、列表list、元组tuple
集合:可变集合set、不可变集合frozen set
映射:字典dict
python是C语言实现的,都是C语言设计的结构体
示例:int(1)在内存:应用计数和类型
2、高效的固定类型数组:ndarray
list: 支持存储不同类型数据可以动态增加长度
计算性能一般
存储冗余多
ndarray: 只能存储单一数据类型
不可以动态增加长度
计算性能好
存储冗余少
3、ndarray的基本用法
import numpy as np #导入模块,并命名为npx = np.array([[1,2,3],[4,5,6]]) #创建一个ndarray数组
x
array([[1,2,3],
[4,5,6]])
type(x) #查看类型
numpy.ndarray
4、ndarray的属性
|
二、创建 ndarray
创建方式
array(object,dtype = None,copy = True,order = 'K',subok = False,ndmin = 0)object: 列表或任何一个_array_方法 返回一个数组的对象
dtype: 数组元素的数据类型,支持自动向更高精度转换
order: 数组元素在内存的储存顺序
C语言风格,行优先
Fortran风格,列优先
从函数创建 array
定义一个函数,根据下标计算每个位置上的值from function(function,shape,**kwargs)
function:定义一个函数,接受N个参数(N维度数),返回一个数值
shape:要创建的数组每个维度的大小
创建多维数组:
import numpy as np # 导入模块,并命名为np x1 = np.array(list) # 创建一个ndarray二维数组,里面为python容器 x2 =np.array([np.arange(2),np.arange(2)]) # 输出[[0,1],[0,1]] x3 = np.array([[1,2,3],[4,5,6]]) # 创建一个ndarray二维数组
创建一个[a,b]范围内取n点的等间距分布数组
x4 =np.linspace(0,10,4,endpoint= True) #默认True 输出[0. 3.33333333 6.66666667 10. ] x5 =np.linspace(0,10,4,endpoint=False) #输出[0. 2.5 5. 7.5]特殊多维矩阵
b = np.ones((1, 2)) #创建一个值均为 1 的1*2维ndarray对象 c = np.full((2, 2), 7) #创建一个值均为 7 的2*2维ndarray对象 d = np.eye(2) #创建一个2*2维对角矩阵 e=np.eye(3,k=2) #第一个参数:行数=列数,即行数或列数 #第二个参数k:默认情况下输出的是对角线全“1” ,其余全“0” 的方阵, #如果k为正整数,则在右上方第k条对角线全“1” 其余全“0” ,k为负整数则 #在左下方第k条对角线全“1” 其余全“0” ,详情如下图。
三、numpy中的数据类型
|
自定义数据类型:
T=np.dtype([('name', np.str_, 40), ('numitems',np.int32), ('price',np.float32)]) products = np.array([('DVD',42,3.14),('Butter',13,2.72)],dtype=T) #插入数据 print(products.dtype) #输出:[('name', '<U40'), ('numitems', '<i4'), ('price', '<f4')] #遍历获取自定义数组的元素 for i in range(products.size): # 控制元素 for j in range(len(products[i])): # 控制元素里面的元素 print(products[i][j])
四、ndarray的文件IO
1.保存为二进制文件
保存单个 array(.npy文件)
np.save(file,arr,allow_pickle=True,fix_imports=True)allow_pickle:允许使用pickle的方式保存对象。出于安全性和兼容性考虑,会禁用pickle
安全性:加载一个pickle的数据时,会执行任何代码
兼容性:pickle对象对版本有要求,不同版本python不兼容
保存多个 array(.npz文件)
np.savez(file,*args,**kwargs)*args:以列表参数的方式指定要保存的array,无法保存array变量名,加载时通过arr_0,arr_1这种方式获取。
**kwargs:以命名参数的方式指定array,加载时可以通过名称获取array
保存多个array并压缩(.npz文件)
np.savez_compressed(file,*args,**kwargs)2.加载二进制文件
语法:np.load(file,mmap_mode=None,allow_pickle=True,fix_imports=True,encoding='ASCII')
***- mmap_mode:可选值(None,'r+','r','w+','c')。如果不是None,则会用指定的模式把内存块映射为一个file对象。
可以实现访问array中的一部分而不用把整个array导入内存
- fix_imports:只在python3中读取python2 生成含pickle对象的文件时有用
- encoding: 只在python3中读取python2 生成含pickle对象的文件时有用
可选值有('latin1','ASCII',bytes)
np.load 可以支持。npy和,npz文件的读取
-读取.npy文件直接返回array
-读取。npz文件,返回一个NpzFile对象(用完close),可以通过.key()方法查看包含的array
3.保存为文本文件
语法:Signature:np.savetxt(fname,X,fmt= '%.18e',delimiter='',newline='\n',header='',footer='',comments='#')
-fname:文件名,若以.gz结尾则自动以gzip压缩
-X: 要保存的array
-fmt: 保存格式
-delimiter:分隔符
-newline: 换行符
-header: 首行输出内容
-footer: 末行输出内容
-comments: 在header和footer前插入的字符,表示注释
4.加载文本文件
语法:Signature:np.loadtxt(fname,dtype=<type 'float'>,comments= '#',delimiter=None,concerters=None,
skiprows=0,usecols=None,skiprows=0,uppack=False,ndmin=0)
-fname:文件名,若以.gz结尾则自动以gzip压缩
-X : 要保存的array
-fmt : 保存格式
-delimiter:分隔符
-newline : 换行符
-header : 首行输出内容
-footer : 末行输出内容
-comments : 在header和footer前插入的字符,表示注释
-concerters : 转换函数字典,通过下标key,为每列定义一个转换函数
-skiprows : 跳过开头的若干行
-usecols : 使用指定列,下标0开始
-uppack : 若为 True,可以用变量捕获每一列
-ndmin : 最小的维度数
五、ndarray进阶
1 操作多维数组 ndarray
ndarray数组的索引
切片(Slicing)
-访问一段数据/切片对象
slice(start,stop,step)
: 所有元素
1: 索引>=1的元素
:3 索引<=3的元素
-2: >=倒数第2个
1::2 >=1开始,以2为步长取到结束
2 遍历数组:
遍历每一个元素:
x = np.arange(12).reshape((3,4)) for element in x.flat: #flat 迭代器 print element
按行遍历(即沿第一个维度切片)
x = np.arange(12).reshape((3,4)) for row in x print row
沿任意维度遍历
x = np.arange(24).reshape((2,3,4)) for i in range(x,shape[1]): #获取指定维度大小 print x[:,i,:] #对这个维度上的每一个截面切片
访问二维数组
#encoding:utf-8 import numpy as np heros = np.array([['苏轼','陈咬金','廉颇'], ['后羿','公孙丽','狄仁杰']],dtype='U8') print(heros[0][2]) print(heros[:,1]) #获取所有行 第二列 print(heros[:,2]) #获取所有行 前二列 print(heros[:,::2]) #获取所有行,所有列,步长为2 输出: [['苏轼' '廉颇'] ['后羿' '狄仁杰']]
3 访问多维数组
arr_1 = np.array([ #一栋房子三层,两行,四列 [ ["苏烈","程咬金","廉颇","亚瑟"], ["后羿","公孙离","狄仁杰","鲁班"], ], [ ["王昭君","安其拉","貂蝉","小乔"], ["孙膑","大乔","鬼谷子","蔡文姬"] ], [ ["王lang","刘邦","刘备","孙悟空"], ["相遇","刘禅","周庄","东皇太一"] ] ]) # print(arr_1) print(arr_1[2][1][3]) #获取第三层第二行第四列。输出:东皇太一 print(arr_1[0,1,:]) #获取第一层第二行所有值。输出:['后羿' '公孙离' '狄仁杰' '鲁班'] print(arr_1[0,1,::2]) #获取第一层第二行步长为2。输出:['后羿' '狄仁杰']
每个维度都可以指定一个索引数组
x = np.arange(10,19).reshape((3,3)) idx1 = [0,1,2] idx2 = [2,1,0] print '原始数组:\n',x print '获取\n',x[idx1,idx2]
每个维度都可以指定一个多维索引数组
x = np.arange(10,19).reshape((3,3)) idx1 = np.arange([[0,0],[1,1]]) idx2 = np.arange([[2,1],[2,1]]) print '原始数组:\n',x print '获取\n',x[idx1,idx2]
增加维度:newaxis:将原数组作为新的更高维数组中的一个切片
x = np.arange(6).reshape((2,3)) y = x[:,:,np.newaxis] #将二维数组的第三维作为1,形成三维数组 print y print y.shape网格函数ix_
以二维网格为例,假设x是一个二维数组
x[np.ix_]
4 bool 数组
创建布尔(bool)数组
直接创建:
x = np.array([True,False,True,False]) print x [True,False,True,False]
通过比较操作符计算得到:
x = np.arange(6).reshape((2,3)) print x>3 # 运算符 [False,False,False] [False,True,True]
通过通用函数计算
x = np.arange(6).reshape((2,3)) print np.greater(x,3) #使用numpy函数创建 [False,False,False] [False,True,True]
六、ndarray操作维度
1、改变ndarray 形状方法
ndarray 的形状即shape属性-数组每个维度的大小
x.np.array([[1,2,3],[4,5,6]])
x.shape
-通过reshape方法改变 ndarray 形状
numpy.reshape(a,newshape,order='C')
#a: 需要改变形状的数组
#newshape:新的形状tuple,其中有一个维度为-1,会根据数组总长和其它维度计算出来
#order: 以这个顺序来读取a中的元素,可选值{''C,'F','A'}
a.reshape(newshape,order='C')
#返回一个指定形状的新数组
-通过 resize 方法改变 ndarray 形状
numpy.resize(a,newshape)
a.resize(newshape,refcheck=True)
#修改数组a的形状为newshape,newshape的大小不一定要和原来的数组大小相同
print('-----------修改多维数组--------------') line = np.arange(24) print(line) 方法1 result = line.reshape(2,3,4) #操作数组的投影(视图)(先复制,再修改) print(result) 方法2 line.shape = (2,3,4) #直接修改数组的形状 print(line) 方法3 line.resize(2,3,4) #修改数组的形状 print(line)
print('-------将三维数组展平成一位数组-------') d3 = np.arange(24).reshape(2,3,4) d1 = d3.ravel() #直接修改数组 print(d3) d2 = d3.flatten() #操作数组的投影(视图)(先复制,再修改) print(d2)
2、合并多个 ndarray
方法 用途row_stack(tup) 多个一维array当作行,合并成2维(按行方法拼接)== vstack(效果一样)
column_stack(tup) 多个一维array当作列,合并成2维(按列方法拼接)==hstack(效果一样)
vstack(tup) 沿第一个维度合并(垂直方向拼接)
hstack(tup) 沿第二个维度合并(水平方法拼接)
stack(tup,axis) 在一个新维度上合并(相当于新建一个维度,在那个维度上 concatenate)
-tup需要合并的arr元组
-axis在这个维度上合并
concatenate(tup,axis=0) 沿第指定维度合并 ---------通用公式
3、一个 ndarray 拆分成多个
方法 用途hsplit(arr,indices) 水平方法拆分(拆分多列,等于split中axis=1)
vsplit(arr,indices) 垂直方向拆分(拆成多列,等于split中axis=0)
-axis 拆分的维度
split(arr,indices,axis=0) 沿着指定方向拆分------------通用公式
七、ndarray 基本运算
1 算术运算:
+,-,/,*,//(floor division整除),**(幂),%(取模)算数运算都是针对相同位置的元素进行的。
更新运算符:+=,-=,*=,/=,**=
2 比较运算:
同算术运算,返回bool值
还可以通过通用函数:算术函数 来进行计算
3 判断:
np.all(alltrue) 判断array 是否所有元素都为True
np.any(sometrue) 判断array 是否至少有一个True
4 聚合计算:沿着一个指定维度计算汇总
np.average 加权平均值(arr1 , weights = arr2)np.mean 算术平均值(arr1)
np.median 计算中位数
np.sum 求和
np.prod 求乘积(阶乘)
np. cumprod 数组的累积乘积
np.min 求最小
np.max 求最大
np.bincount 计算每个元素出现的次数
import numpy as np arr2 = np.array([2,3,4,5]) prod_2 = np.cumprod(arr2) print(prod_2) #输出:[ 2 6 24 120]
5 查找和排列
np.argmin 沿指定维度查找最小值下标
np.argmax 沿指定维度查找最大值下标
np.nonzero 查找非零元素的下标
np.where(condition) 根据条件查找或替换
np.take(column,index) #根据索引获取值
np.argsort 沿着指定维度计算下标,按这个下标元素是递增的
np.sort 沿指定维度 元素按递增顺序排序
np.lexsort 根据多个array进行排序
6 数组的修剪
arr1. clip(num1,num2) arr1= [0 1 2 3 4] Clipped [1 1 2 2 2]
7 数组的压缩
利用compres ()函数计算:返回一个根据给定条件筛选后的数组。线性代数
8 自定义函数
9 广播
让两个不同维度的 array进行元素运算
若维数较小的array增加1的维度,知道两者维数相等
x = np.arange(6).reshape((2,3)) y = np.arange(9).reshape((3,3)) x[:,np.newaxis,:]+y array([ [[0,2,4], [3,5,7], [6,8,10]] [[3,5,7], [6,8,10], [9,11,13]] ])
10 array几种copy模式
完全不拷贝
赋值时,只是引用x = np.array([1,2,3,4]) y = x y is x True
视图(浅拷贝)
视图会创建一个新 array 对象,但和原来的 array 共享同一份数据创建视图:ndarray.view/通过切片
判断一个array是否为视图
ndarray.flags.owndata
示例:
#通过ndarray.view 创建 x = np.array([1,2,3,4]) y = x.view() print 'y.flags.owndata:',y.flags.owndata print 'y.base is x:',y.base is x y.flags.owndata:False y.base is x:True
深拷贝
即:完全copy。创建新拷贝
--ndarray.copy()
--通过索引数组和布尔数组获取新的array(又称为Fancy Indexing)