Numpy基础:数组和矢量运算
目录:
尊重原创,转载出处:https://blog.csdn.net/sunyaowu315/article/details/82733249?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
一 Numpy及其重要性
Numpy(Numerical Python)是高性能科学计算和数据分析的基础包,它是几乎所有数据分析高级工具的构建基础。
① ndarray ,一个具有矢量算数运算和复杂广播能力的快速且节省空间的多维数组。
② 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。
③ 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。
④ 线性代数、随机数生成及傅里叶变换功能。
⑤ 用于集成由C,C++,Fortran等语言编写的代码的工具CAPI,将数据传递给外部库(生态系统角度)。
⑥ Numpy本身并没有提供多么高级的数据分析功能,理解Numpy数组以及面向数组的计算将有助于你更加高效地使用pandas等工具。精通面向数组的编程和思维方式是成为Python科学计算牛人的一大关键步骤。
对于大部分数据分析应用而言,最关注的功能主要集中于:
① 用于数据整理、自己构建、过滤、转换等快速的矢量化数组运算。
② 常用的数组算法,如排序、唯一化、集合运算等。
③ 高效的描述统计和数据聚合/摘要运算。
④ 用于异构数据集的合并/连接运算的数据对齐和关系型数据运算。
⑤ 将条件逻辑表述为数组表达式(而不是带有if-elif-else分支的循环)。
⑥ 数据的分组运算(聚合、转换、函数应用等)。
二 ndarray:一种多维数组对象
Numpy最重要的一个特点就是其N维数组对象:ndarray,该对象是一个快速而灵活的大数据集容器。可以利用这种数组对整块数据执行一些数学运算,其语法与标量元素之间的运算一样。
ndarray是一个通用的同构数据多维容器,其中所有的元素必须是相同类型的。每个数组都有一个shape(一个表示各维度大小的元组)和一个dtype(一个用于说明数据类型的对象)。
data.shape() (2,3)
data.dtype() ('float64')
1 创建ndarray
序列型的对象
data = [1,2,3,4]
arr = np.array(data)
嵌套序列,嵌套序列将会被转换为一个多维数组。
np.array会尝试为新建的数组推断出一个较为合适的数据类型,数据类型保存在一个特殊的dtype对象中。
其他的创建数组的函数。
np.zeros() #指定长度或形状的数组全部为0
np.ones() #指定长度或形状的数组全部为1
np.empty() #空数组
np.arange() #python内置函数的数组版
2 ndarray的数据类型
dtype(数据类型)是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息:
arr = np.array([1,2,3],dtype = np.float64)
arr.dtype()
dtype是Numpy如此强大和灵活的原因之一。
Numpy的数据类型:
int8/uint8——有符号和无符号
float64——浮点型
complex64——复数
bool——布尔型
object——python对象类型
string_——字符串类型
unicode——unicode类型
可以通过ndarray的astype方法显式地转换其dtype
float_arr = arr.astype(np.float64)
调用astype无论如何都会创建出一个新的数组(原始数据的一份拷贝),即使新dtype跟以前的一样
3 数组和标量之间的运算
数组很重要,因为它使你不用编写循环即可对数据执行批量运算。这通常就叫做矢量化。
大小相等的任何算术运算都会将运算应用到元素级。
数组与标量的算术运算也会将那个标量值传播到各个元素。
不同大小的数组之间的运算叫做广播(广播机制)。
4 基本的索引和切片
Numpy数组的索引是一个内容丰富的主题,因为选取数据子集或单个元素的方式有很多。
将一个标量值赋值给一个切片时,该值会自动广播到整个选区。
跟列表最重要的区别在于,数组切片是原始数组的视图,这意味着数据不会被复制,视图上的任何修改都会直接反映到源数据上。如果需要一份副本而非本视图,则需要显式复制操作:arr.copy()。
Numpy的设计目的是处理大数据。Numpy将数据来回复制的话将会产生很多性能和内存问题。
① 元素索引
对于高维度数组,能做的事情更多。在一个二维数组中,各索引位置上的元素不再是标量,而是一维数组。
可以对高维数组各个元素进行递归访问,也可以传入一个逗号隔开的索引列表来选取单个元素。
arr2d = np.array([1,2,3],[4,5,6],[7,8,9])
arr2d[0][2] = arr2d[0,2] = 3
② 切片索引
nadrray的切片语法跟python列表这样的一维对象差不多。
高纬度对象的切片花样比较多。可以在一个轴或者多个轴上进行切片,也可以跟整数索引混合使用。
arr2d[:2,1:] #只能得到相同维数的数组视图
arr2d[1,:2] #通过将整数索引和切片混合,可以得到低维度的切片
arr2d[:,:1] #只有冒号表示选取整个轴
③ 布尔型索引
判断满足条件
data[names = 'bob',2:] #布尔型数组的长度必须跟被索引的轴长度一致,此外,还可以与切片、整数等混用
④ 花式索引
花式索引是一个Numpy术语,它指的是利用整数数组进行索引
arr = np.empty((8,4))
arr[[4,3,0,6]] #只需传入一个用于指定顺序的整数列表或ndarray即可
arr[[-3,-5,-7]] #使用负数索引将会从末尾开始选取行
arr = np.arange(32).reshape((8,4))
arr[[1,5,7,2],[0,3,1,2]] #一次传入多个索引数组会有些特别
⑤ 数组转置和轴对换
转置(transpose)是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)
T属性。进行矩阵计算时,经常需要用到该操作。
三 通用函数:快速的元素级数组函数
通用函数(ufunc)是一种对nadrray中的数据执行元素级运算的函数。可以将其看做简单函数(接受一个或多个标量值,并产生一个 或多个标量值)的 矢量化包装器。
许多ufunc都是简单的元素级变体。如np.sqrt() /np.exp()
一元ufunc(接受一个数组):
abs/fabs #绝对值 ,非负数的绝对值。
sqrt #计算各元素平方根。
square #计算各元素平方。
exp #计算各元素指数。
log/log10/log2/log1p #计算各元素的自然对数。
sign #计算各元素的正负号。
ceil #计算各元素的ceiling值,即大于等于该值的最小整数。
floor #计算各元素的floor值,即小于等于该值的最大整数。
rint #将各元素四舍五入到最接近的整数。
modf #将数组的小数和整数部分以两个独立数组的形式返回。
isnan #返回一个表示“哪些值是NaN”的布尔型数组。
isfinite/isinf #返回表示无穷的布尔型数组。
cos/cosh/sin/sinh/tan/tanh #三角函数
二元ufunc(接受两个数组):
add #将数组中对应的元素相加
subtract #从第一个数组中减去第二个数组中的元素。
multiply #数组元素相乘。
divide/floor_divide #除法或向下圆整除法,丢弃余数。
power #计算第二个数组元素b相对于第一个数组中元素a的计算:a的b次方。
maximum/fmax #元素级的最大值计算,忽略NaN。
minimum/fmin #元素级的最小值计算,忽略NaN。
copysign #将第二个数组的值得符号复制给第一个数组中对应的值。
greater/greater_equal/less/less_equal/equal/not_equal #执行元素级的比较运算,最终产生布尔型数组。
logical_and/logical_or/logical_xor #执行元素级的真值逻辑运算 (与或非)。
四 利用数组进行数据处理
Numpy数组可以将许多种数据处理任务表述为简洁的数组表达式(否则需要编写循环)。
用数组表达式代替循环的做法,通常被称作矢量化。一般来说,矢量化数组运算比等价的纯python方法快1~2个数量级(甚至更多)。
广播——是一种针对矢量化计算的强大手段。
1 将条件逻辑表述为数组计算
在数据分析中,where通常用于根据一个数组而产生一个新的数组。
np.where函数是三元表达式x if condition else y 的矢量化版本。
np.where的第二个和第三个参数不必是数组,传递给where的数组大小可以不相等,甚至可以是标量值。
多层嵌套使用,功能更加强大。
2 数学与统计方法
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算、聚合运算(aggregation 通常叫做约简)。
基本数组统计方法:
sum #对数组中全部或者轴向的元素求和。
mean #算术平均数
std/var #分别为标准差和方差,自由度可调
min/max #最大值和最小值
argmin/argmax #最大和最小元素的索引
cumsum #累计和
cumprod #累计积
sum和mean等函数可以接受一个axis参数,用于计算轴向的统计值,得到一个少一维的数组。
cumsum、cumprod之类的方法不聚合,产生一个由中间结果组成的数组。
3 用于布尔型数组的方法
4 排序
跟python一样,Numpy数组也可以通过sort方法就地排序。
多维数组可以在任意一个轴上进行排序,只要给出轴编号传给sort即可。
arr.sort()
顶级方法返回的是数组的已排序副本,而就地排序会修改数组本身。
计算数组分位数最简单的方法是对齐进行排序,然后选取特定位置的值。
5 唯一化及其他的集合逻辑
Numpy提供了一些针对一维ndarray的基本集合运算。
数组的集合运算:
unique(x) #计算x中的唯一元素,并返回有序结果。等价于纯python代码中的set()。
intersect1d(x,y) #计算x和y中的公共元素,并返回有序结果。
union1d(x,y) #计算x和y的并集,并返回有序结果。
in1d(x,y) #得到一个表示“x是否包含于y”的布尔型数组。
setdiff1d(x,y) #集合的差,即元素在x中且不在y中。
setxor1d(x,y) #集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素。
五 用于数组的文件输入输出
Numpy可以读写磁盘上的文本数据或者二进制数据
np.save和np.load是读写磁盘数组数据的两个主要函数
arr = np.loadtxt('array_ex.txt',delimiter = ',')
arr = np.savetxt()
六 线性代数
线性代数(如矩阵乘法、矩阵分解、行列式及其他方阵数学等)是任何数据库的重要组成部分。
Numpy.ligalg中有一组标准的矩阵分解运算以及诸如求逆合行列式之类的东西:
diag #以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0)。
dot #矩阵乘法。
trace #计算对角线元素的和。
det #计算矩阵行列式。
eig #计算方阵的本征值和本征向量。
inv #计算方阵的逆。
pinv #计算矩阵的MP伪逆。
qr #计算QR分解。
svd #计算奇异值分解(SVD)。
solve #解线性方程组ax = b,其中a为一个方阵。
lstsq #计算ax = b的最小二乘解。
七 随机数生成
Numpy.random模块对python内置的random进行了补充,增加了一些用于高效生成多种概率分布的样本值函数。而python内置的random模块则只能一次生成一个样本值,且需要生成在大量样本值时,Numpy.random快了不止一个量级。
部分Numpy.random函数:
seed #确定随机数生成器的种子。
permutation #返回一个序列的随机排列或返回一个随机排列的范围。
shuffle #对一个序列就地随机排列。
rand #产生均匀分布的样本值。
randint #从给定的上下限范围内随机选取整数。
randn #产生正态分布(平均值为0,标准差为1)的样本值。
binomial #产生二项分布的样本值。
normal #产生正态(高斯)分布的样本值。
beta #产生beta分布的样本值。
chisquare #产生卡方分布的样本值。
gamma #产生gamma分布的样本值。
uniform #产生在[0,1]中 均匀分布的样本值。
随机漫步
通过模拟随机漫步来说明如何而运用数组运算。
首次穿越时间。
一次模拟多个随机漫步。