Numpy 数组ndarray和常用函数速查

转自:DawnRanger的专栏
https://blog.csdn.net/DawnRanger/article/details/53125945




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 np
arr1 = np.array([1,2,3,4,5])
arr2 = np.array([[1,2,3,4], [5,6,7,8]]) # 二维数组

  
  
  • 1
  • 2
  • 3
  • 4

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

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

  
  
  • 1
  • 2
  • 3
  • 4

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])

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

扫描二维码关注公众号,回复: 1917652 查看本文章
np.arange(15)

  
  
  • 1
  • 2

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

  • array 将输入转换为ndarray,默认直接复制输入数据
  • asarray 将输入转换为ndarray,如果输入本身就是一个ndarray就不进行复制
  • ones_like/zeros_like/empty_like 以另一个数组为参数,并根据其形状和dtype创建一个全0/全1/空数组
  • eye/identify 创建一个N×N” role=”presentation”>N×NN×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.dtype Out[5]: dtype('float64') arr2.dtype Out[6]: dtype('int32')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

2.3 ndaray与标量的计算

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

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

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

2.4 索引与切片

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

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

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

如果一定要复制可以使用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]  # 这两种索引方法等价

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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]])

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

可以看出,它是按第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]])

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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无效)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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

  
  
  • 1
  • 2
  • 3

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

正常情况下的索引:

In [17]: arr = np.empty((8,4))
In [18]: for i in range(8):
    ...:     arr[i] = i # 矢量化赋值
In [19]: arr
Out[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.]])

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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

In [24]: arr = np.arange(32).reshape((8,4))
In [25]: arr
Out[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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

最终选出的元素是(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]])

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

另一种方法是使用 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]])

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

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,负值设置为-2
np.where(arr>0, 2, arr) # 只讲正值设置为2 

  
  
  • 1
  • 2
  • 3
  • 4

条件是可以嵌套的:

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

  
  
  • 1
  • 2
  • 3
  • 4

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() # 测试数组中是否存在一个或多个True
bools.all() # 检查数组中所有值是否都是True

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

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%分位数

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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]之间的均匀分布





1. 简介

猜你喜欢

转载自blog.csdn.net/qq_23869697/article/details/80929772