NumPy学习笔记

来源:互联网 发布:jira配置数据库 编辑:程序博客网 时间:2024/05/16 19:34

1. 简介

Numeric Python的简称,是几乎所有python科学计算工具的基础。主要功能:

  • ndarray: 一个具有矢量运算和复杂广播能力的快速并且节省空间的多维数组
  • 面向数组的运算: 对于数组进行快速运算的标准数学函数
  • 磁盘读写、内存映射
  • 线性代数、随机数、傅里叶变换

NumPy本身并没有提供什么高级的数据分析能力,但是理解NumPy数组以及面向数组的计算将有利于使用pandas等工具。

2. ndarray:一种多维数组对象

ndarray是一个通用的同构数据多维容器,其中的所有元素必须是相同类型的。ndarray含有两个属性:

  • shape: 一个表示各维度大小的数组
  • dtype:一个用于说明数据类型的对象

2.1 创建ndaray

1) array函数

它接受一切序列型的对象(list/set/tuple/ndarray/…)。除非显式说明,np.array会尝试为新建的这个数组推断出一个较为合适的数据类型:

import numpy as nparr1 = np.array([1,2,3,4,5])arr2 = np.array([[1,2,3,4], [5,6,7,8]]) # 二维数组

2) zeros/ones/empty函数
创建指定长度或形状的全0或全1或空数组,只需传入一个表示形状的元组(tuple)即可:

np.zeros(10)np.ones((3,6)np.empty((2,3,2)) #注意返回的并不是全0数组,而是未初始化的随机值

3) linspace函数linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
返回在start到stop之间均匀分布的num个数字,可以选择是否包括stop. retstep表示是否返回步长.

np.linspace(1,5,5,True)Out[4]: array([ 1.,  2.,  3.,  4.,  5.])np.linspace(1,5,5,False)Out[5]: array([ 1. ,  1.8,  2.6,  3.4,  4.2])

3) arange函数arange([start,] stop[, step,], dtype=None)
python内置函数range的数组版

np.arange(15)

4) 其它函数:
由于NumPy关注的是数值计算,因此,如果没有特别指定,数据类型基本都是float64(浮点数)

  • array 将输入转换为ndarray,默认直接复制输入数据
  • asarray 将输入转换为ndarray,如果输入本身就是一个ndarray就不进行复制
  • ones_like/zeros_like/empty_like 以另一个数组为参数,并根据其形状和dtype创建一个全0/全1/空数组
  • eye/identify 创建一个N×N单位矩阵(对角线为1,其余为0)

2.2 ndaray的数据类型

dtype含有ndarray将一块内存解释为特定数据类型所需要的信息

arr1 = np.array([1,2,3], dtype = np.float64)arr2 = np.array([1,2,3], dtype = np.int32)# arr2 = np.array([1,2,3], dtype = 'i4') # 也可以写类型代码arr1.dtypeOut[5]: dtype('float64')arr2.dtypeOut[6]: dtype('int32')

NumPy的数据类型

  • int8/int16/int32/int64 有符号8/16/32/64位整数,类型代码 i1/i2/i4/i8 (分别为1/2/4/8个字节)
  • uint8/uint16/uint32/uint64 无符号8/16/32/64位整数,类型代码 u1/u2/u4/u8
  • float16/float32/float64/float128 浮点数,类型代码 f2/f4/f8/f16
  • complex64/complex128/complex256 复数,类型代码 c8/c16/c32
  • bool 布尔类型 ,类型代码 ?
  • object Python对象类型,类型代码 O
  • string_ 固定长度的字符串类型(每个字符一个字节),类型代码 S 。例如,要创建一个长度为10的字符串,应使用S10
  • unicode 固定长度的unicode类型,类型代码 U 。同字符串(如U10)

数据类型转换: astype方法

int_arr = np.array([1,2,3,4,5])float_arr = int_arr.astype(np.float64)numeric_str = np.array (['1.25', '-9.6', '42'], dtype = np.string_)float_arr = numeric_str.astype(float)  # 这里的float是Python的数据类型,NumPy会自动的将其映射到等价的dtype上,即np.float64

注意:astype无论如何都会创建出一个新的数组(原始数据的一分拷贝)

2.3 ndaray与标量的计算

使用数组运算的好处是不写循环即可对数据进行批量运算,即矢量化(vectorization)。需要注意的是:

  • 大小相等的数组之间的任何算术运算都会将运算应用到元素级
  • 数组与标量的算术运算会将标量值传播到各个元素

不同大小的数组之间的运算叫做广播(broadcasting)。

2.4 索引与切片

2.4.1 一维数组
一维数组的索引与切片和Python列表的功能类似,区别在于,数组切片是原始数组的视图,这意味着数据不会被复制,对视图的任何修改都会直接反映到原数组上。NumPy如此设计的目的是为了处理大数据,如果采取复制的方法可能产生性能和内存的问题。

arr = np.arange(10)arr[5:8] = 12arrOut[10]:array([0, 1, 2, 3, 4, 12, 12, 12, 8, 9])

如果一定要复制可以使用copy方法显式的复制。

2.4.2 多维数组
多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray。例如,二维数组中,各索引位置上的元素不再是标量而是一维数组。

arr2d = np.array([[1,2,3], [4,5,6], [7,8,9]])arr2d[2]Out[11]:array([7, 8, 9])arr2d[0][2]arr2d[0,2]  # 这两种索引方法等价

2.4.3 多维数组切片
多维数组切片与一维数组稍有不同

arr2d = np.array([[1,2,3], [4,5,6], [7,8,9]])arr2d[:2]Out[1]: array([[1,2,3],                [4,5,6]])

可以看出,它是按第0轴(第一个轴)切片的。切片是沿着一个轴向选取元素的。
可以一次传入多个切片,也可以将整数索引和切片混合:

arr2d[:2, 1:]Out[2]: aray([[2,3],               [5,6])arr2d[1, :2]Out[3]: array([4, 5])arr2d[:, :1]Out[4]: aray([[1],               [4],               [7]])

2.4.4 布尔型索引
与算数运算类似,数组的比较运算(如==)也是矢量化的。

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])data = np.random.randn(7, 4)  # 产生7x4的随机数组names == 'Bob'Out[5]: array([True, False, False, True, False, False, False], dtype = bool)data[names == 'Bob'] # 布尔索引data[names = 'Bob', 2:] # 布尔索引与切片data[-(names == 'Bob')]mask = (names == 'Bob') | (names = 'Will') # 多个布尔条件用&(与)、|(或)等连接起来。(and/or无效)

通过布尔型索引选取数组中的数据,将总是创建副本,即使返回一模一样的数组。通过布尔型数组设置值是常用的手段。例如:

data[data<0] = 0  # 将data中的所有的负值都设为0data[names != 'Joe'] = 7  # 将不为Joe的值设为7 

2.4.5 花式索引(Fancy indexing)
利用整数数组进行索引。

正常情况下的索引:

In [17]: arr = np.empty((8,4))In [18]: for i in range(8):    ...:     arr[i] = i # 矢量化赋值In [19]: arrOut[19]:array([[ 0.,  0.,  0.,  0.],       [ 1.,  1.,  1.,  1.],       [ 2.,  2.,  2.,  2.],       [ 3.,  3.,  3.,  3.],       [ 4.,  4.,  4.,  4.],       [ 5.,  5.,  5.,  5.],       [ 6.,  6.,  6.,  6.],       [ 7.,  7.,  7.,  7.]])In [23]: arr[[4,3,0,6]]  # 选取多行,注意要加括号[]Out[23]: array([[ 4.,  4.,  4.,  4.],       [ 3.,  3.,  3.,  3.],       [ 0.,  0.,  0.,  0.],       [ 6.,  6.,  6.,  6.]])

一次传入多个索引数组时,它返回的是一个一维数组,其中的元素对应各个索引元组。

In [24]: arr = np.arange(32).reshape((8,4))In [25]: arrOut[25]:array([[ 0,  1,  2,  3],       [ 4,  5,  6,  7],       [ 8,  9, 10, 11],       [12, 13, 14, 15],       [16, 17, 18, 19],       [20, 21, 22, 23],       [24, 25, 26, 27],       [28, 29, 30, 31]])In [26]: arr[[1,5,7,2], [0,2,1,3]]Out[26]: array([ 4, 22, 29, 11])

最终选出的元素是(1, 0)、(5, 3)、(7, 1)、(2, 2)。
如果想要选取数组的行列子集,可以采用以下方法:

In [33]: arr[[1,5,7,2]][:,[0,3,1,2]]  # 可以把左右两个[]分开来理解Out[33]: array([[ 4,  7,  5,  6],       [20, 23, 21, 22],       [28, 31, 29, 30],       [ 8, 11,  9, 10]])

另一种方法是使用 np.ix_ 函数,它可以将两个一维整数数组转换为一个用于选取方形区域的索引器:

In [34]: arr[np.ix_([1,5,7,2],[0,3,1,2])]Out[34]: array([[ 4,  7,  5,  6],       [20, 23, 21, 22],       [28, 31, 29, 30],       [ 8, 11,  9, 10]])

与切片不同,花式索引总是将数据复制到新数组中

2.5 数组转置和轴变换

返回原数据的视图,不会进行任何复制。数组有transpose/swapaxes方法和T属性。

3. numpy通用函数

一元函数:

  • abs/fabs 绝对值。对于非复数,可以使用更快的fabs
  • sqrt/square/exp/log/log10/log2/log1p 平方根/平方/指数/自然对数/底数为10的log/底数为2的log
  • sign 返回元素的符号:1(正数)、0(零)、-1(负数)
  • ceil/floor 取上界/下界整数
  • rint 四舍五入到整数
  • modf 返回数组的小数和正数两个独立的数组
  • isnan 返回布尔数组,判断是否为数字
  • isfinite/isinf 是否有穷/无穷
  • cos/cosh/sin/sinh/tan/tanh 普通和双曲三角函数

二元函数:

  • add/subtract/multiply/divide/floor_divide 加/减/乘/除/向下圆整除法
  • power 第一个数组中的是底数,第二个数组中的是指数
  • maximum/fmax/minimum/fmin 最大最小值(fmax/fmin忽略NaN)
  • mod 取模
  • copysign 将第二个数组中的值的符号复制给第一个数组中
  • greater/greater_equal/less/less_equal 元素级比较,产生布尔数组。
  • logical_and/logical_or/logical_xor 元素级真值逻辑运算。&、|、^。

4. 利用数组进行数据处理

一般来说矢量化数组运算要比等价的纯Python方式快上一两个数量级,尤其是各种数值计算。广播是一种针对矢量化计算的强大手段。

4.1 将条件逻辑表述为数组运算

numpy.where 函数是三元表达式 x if condition else y 的矢量化版本:where(condition, [x, y])

arr = randn(4,4)np.where(arr>0, 2, -2) # 争执设置为2,负值设置为-2np.where(arr>0, 2, arr) # 只讲正值设置为2 

条件是可以嵌套的:

np.where(cond1 & cond2, 0,         np.where(cond1, 1,                 np.where(cond2, 2, 3)))

4.2 数学和统计方法

聚合计算(aggregation):既能当数组的实例方法调用,也可以当做顶级NumPy函数使用;可接受一个 axis 参数
- sum/mean/std/var/min/max/argmin/argmax 求和,平均数,标准差,方差,最大值,最小值,最大最小元素的索引

不聚合,产生一个由中间结果组成的数组:
- cumsumcumprod 所有元素的累积和/累计积

4.3 用于布尔型数组的方法

bools = np.array([False, False, True, False])(bools>0).sum() # 正值的数量bools.any() # 测试数组中是否存在一个或多个Truebools.all() # 检查数组中所有值是否都是True

4.4 排序

Numpy数组自带sort方法,如果需要在某一个轴向上进行排序,只需要将轴编号传递给sort.
顶级方法np.sort返回的是数组已排序的副本,而数组自带sort方法则会直接修改数组本身.

arr = randn(5, 3)arr.sort(1)large_arr = randn(1000)large_arr.sort()large_arr[int(0.05 * len(large_arr))] # 5%分位数

4.5 唯一化以及其它的集合逻辑

集合运算函数:

  • unique(x) 返回唯一元素
  • intersect1d(x,y) 交集
  • union1d(x,y) 并集
  • in1d(x,y) 布尔型数组,表示x中的元素是否存在于y中
  • setdiff1d(x,y)
  • setxor1d(x,y) 异或

5. 用于数组的文件操作

二进制文件: np.savenp.load
文本文件: np.loadtxtnp.savetxt

6. 线性代数

常用numpy.linalg函数

  • dot 矩阵乘法。两个一维数组计算点乘,两个多维数组计算叉乘
  • diag 返回矩阵对角线元素
  • trace 对角线元素和
  • det 行列式
  • eig 特征值、特征向量
  • inv
  • qr QR分解
  • svd 奇异值分解
  • solve 解线性方程Ax=b
  • lstsq 计算Ax=b的最小二乘解

7. 随机数生成

生成随机数的方法:

  • rand 均匀分布的样本值
  • randint 给定上下限的随机整数
  • randn 标准正态分布
  • binomial 二项分布
  • normal 正态分布
  • chisquare 卡方分布
  • gamma Gamma分布
  • uniform [0,1]之间的均匀分布
0 0
原创粉丝点击