当前位置:   article > 正文

Numpy 基础_numpy基础

numpy基础

一、简介

Numpy,全称Numerical Python,是Python的一个强大的数据分析包。相比于list数据结构,Numpy的ndarray数据结构,支持矢量计算、无需遍历即可完成对整组数据的运算。此外,还提供了诸如转置、点积等线代操作。提供了随机数生成、傅里叶变换等功能。最后,Numpy还可以作为Python和C(C++,Fortran等)进行数据交流的基础。

  1. dt = [[1, 2], [3, 4]]
  2. arr = np.array(dt)
  3. # 数组乘数组——对应位置元素相乘
  4. print(arr*arr)
  5. # 数组乘标量——数组每个元素都乘该标量
  6. print(arr*2)
  7. # 输出:[[ 1 4]
  8. # [ 9 16]]
  9. # [[2 4]
  10. # [6 8]]

二、创建ndarray

创建数组ndarray的常用方法
方法说明
array将序列数据转换为ndarray,指定类型或自动分析类型
asarray同上,区别在于输入为ndarray时,不进行复制
arange使用同range
ones,ones_like生成指定形状值为1的数组
zeros,zeros_like生成指定形状值为0的数组
empty,empty_like生成指定形状值不赋初值的数组
eye,identity根据参数N生成单位矩阵

1.np.array创建数组

  1. import numpy as np
  2. dt = [[2, 1], (1, 2)]
  3. arr = np.array(dt)
  4. print(arr)
  5. # 没有指定类型,自动识别
  6. print(arr.dtype)
  7. # 输出:[[2 1]
  8. # [1 2]]
  9. # int32

2.np.array和np.asarray的区别

  1. dt = [[2, 1], (1, 2)]
  2. arr = np.array(dt)
  3. # 不管什么类型序列,都会新建一个数组
  4. arr2 = np.array(arr)
  5. # 传入是数组,则不会再新建
  6. as_arr = np.asarray(arr)
  7. print('原始数组id:{},使用np.array创建数组的id:{},使用np.asarray创建数组的id:{}'.format(id(arr), id(arr2), id(as_arr)))
  8. # 输出:原始数组id:1913281185152,使用np.array创建数组的id:1913281155680
  9. # 使用np.asarray创建数组的id:1913281185152

3.np.empty创建的并不是空数组

这个方法只是分配了2*3的一个数组空间,未赋值。但并不代表值为空。这些地址空间的值为上一个程序使用之后的结果,存在未知随机风险。

  1. arr = np.empty((2, 3))
  2. print(arr)
  3. # 输出:[[6.23042070e-307 1.89146896e-307 1.42417221e-306]
  4. # [1.37961641e-306 6.23039354e-307 1.69115935e-306]]

 4.np.ones_like生成一个和指定数组一样形状的数组,可指定类型

  1. print(arr.shape)
  2. arr = np.ones_like(arr, dtype='f4')
  3. print(arr)
  4. # 输出:(2, 2)
  5. # [[1. 1.]
  6. # [1. 1.]]
Numpy常用数据类型
类型简写说明
int32,uint32i4,u4有符号和无符号32位整数(4字节)
float64f8或d对应python的float和C的double
complex128c16128位浮点数表示的复数
bool?真假
objectOPython的对象
string_S每个字符占一个字节
unicode_U字节数由平台决定

5.类型转换

注意:无论转换前后,数据类型是否一致,都会创建新的对象。

  1. dt = [[2, 1], (1, 2)]
  2. arr = np.array(dt)
  3. print(arr.dtype)
  4. # 自动对应float64
  5. new_arr = arr.astype(float)
  6. print(new_arr.dtype)
  7. # 输出:int32
  8. # float64

三、索引和切片

1.基本索引和切片

(1) 两种方式访问某个元素

  1. dt = [[1, 2], [3, 4]]
  2. arr = np.array(dt)
  3. # 这种访问方式和二维列表一样
  4. print('第一个元素是:', arr[0][0])
  5. # 还可以这样访问
  6. print('还可以这样访问第一个元素:', arr[0, 0])

 (2)简单切片

  1. dt = [[1, 2, 3], [4, 5, 6]]
  2. # 列表切片
  3. print(dt[0:1])
  4. arr = np.array(dt)
  5. # 数组切片
  6. print(arr[0:1])
  7. # 输出:[[1, 2, 3]]
  8. # [[1 2 3]]

 (3)切片赋值

list的切片会拷贝数据,即修改切片不会改变原列表。同时,赋值号前后应是同样结构的数据。数组的切片则不同。

  1. dt = [1, 2, 3, 4, 5, 6]
  2. arr = np.array(dt)
  3. # 切片所得是两个元素,可以通过广播,赋值为同一个值
  4. arr_slice = arr[1:3]
  5. # 修改切片,原数组也会改变
  6. arr_slice[:] = 0
  7. print(arr)
  8. # 数组:[1 0 0 4 5 6]

2.花式索引

(1)混合索引

  1. dt = [[1, 2, 3], [4, 5, 6]]
  2. arr = np.array(dt)
  3. print('取每一行的第一个元素:', arr[:, 0])
  4. # 输出:取每一行的第一列: [1 4]

 (2)布尔型索引

  1. dt = [1, 2, 3, 4, 5, 6]
  2. arr = np.array(dt)
  3. bl = [True, True, False, True, True, True]
  4. print(arr[bl])
  5. # 输出:[1 2 4 5 6]

 实际不会这样手动构造包含布尔值的列表,而是采用条件表达式。

  1. dt = [1, 2, 3, 4, 5, 6]
  2. arr = np.array(dt)
  3. print(arr[arr != 3])

 (3)花式索引

  1. dt = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  2. arr = np.array(dt)
  3. print('原数组:\n', arr)
  4. # 取第一行和最后一行
  5. print('取第一行和最后一行:\n', arr[[0, -1]])
  6. # 取对角线元素,相当于取(0,0)(1,1)(2,2)
  7. print('取对角线元素:', arr[[0, 1, 2], [0, 1, 2]])
  8. # 输出:原数组:
  9. # [[1 2 3]
  10. # [4 5 6]
  11. # [7 8 9]]
  12. # 取第一行和最后一行:
  13. # [[1 2 3]
  14. # [7 8 9]]
  15. # 取对角线元素: [1 5 9]

 如果想取原数组一个矩形区域,可以使用np.ix_

  1. dt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
  2. arr = np.array(dt)
  3. print('原数组:\n', arr)
  4. print('取中间2*2的数组:\n', arr[np.ix_([1, 2], [1, 2])])
  5. # 输出:原数组:
  6. # [[ 1 2 3 4]
  7. # [ 5 6 7 8]
  8. # [ 9 10 11 12]
  9. # [13 14 15 16]]
  10. # 取中间2*2的数组:
  11. # [[ 6 7]
  12. # [10 11]]

四、数组函数

数组函数和一般的函数没有什么区别,只是它作用在数组上,是简单函数的矢量化包装。

1.一元函数

常用一元函数
函数说明
abs,fabs绝对值,对于非复数,可使用更高效的fabs
square各元素求平方
sigh各元素正负号,1:正数,0:零,-1:负数
ceil,floor向上,向下取整
rint四舍五入到整数,同时保留dtype
modf将整数和小数部分分开返回
isnan数组元素要么是数字要么是np.nan
cos,sin,tan,arcsin三角函数

(1)向上取整

不小于原数的最小整数,输出数据类型为float

  1. dt = [1.4, 2.6, 3.7, 4.8]
  2. arr = np.array(dt)
  3. # 向上取整,并非四舍五入
  4. print(np.ceil(arr))
  5. # 输出:[2. 3. 4. 5.]

(2)分割整数和小数部分 

  1. dt = [1.5, 2.6, 3.7, 4.8]
  2. arr = np.array(dt)
  3. arr_dcm, arr_int = np.modf(arr)
  4. print(arr_dcm, arr_int)
  5. # 输出:[0.5 0.6 0.7 0.8] [1. 2. 3. 4.]

 (3)判断是否是数字

元素只能是数字和np.nan,如传入字符串会报错。

  1. dt = [1.5, 2.6, np.nan, 4.8]
  2. arr = np.array(dt)
  3. print(np.isnan(arr))
  4. # 输出:[False False True False]

 np.nan并不是“是否为空”的判断,而是一个特殊的float对象。

  1. dt = [1.5, 2.6, None, 4.8]
  2. arr = np.array(dt)
  3. print(np.isnan(arr))
  4. # 输出:TypeError: ufunc 'isnan' not supported for the input types
  5. print(np.nan is None)
  6. print(type(np.nan))
  7. # 输出:False
  8. # <class 'float'>

2.二元函数

常用二元函数
函数说明
add,subtract,multiply元素间加,减,乘
divide,floor_divide除,向下整除
powera^b
maximum,fmax逐个比较取大值,fmax会忽略nan
mod元素间求模
copysign将第二组元素符号复制给第一组
greater,less_equal>,<=,返回布尔型数组
logical_and,logical_xor逻辑与,逻辑异或

 (1)向下整除

  1. arr = np.array([1, 2, 3, 4])
  2. arr2 = np.array([5, 6, 7, 8])
  3. print(np.floor_divide(arr2, arr))
  4. # 输出:[5 3 2 2]

(2)相同位置元素取大值

  1. arr = np.array([1, 2, 3, np.nan])
  2. arr2 = np.array([5, 6, 7, 8])
  3. print(np.maximum(arr2, arr))
  4. # 输出:[ 5. 6. 7. nan]

 (3)复制正负号

  1. arr = np.array([1, 2, 3, 4])
  2. arr2 = np.array([1, -1, 1, -1])
  3. print(np.copysign(arr, arr2))
  4. # 输出:[ 1. -2. 3. -4.]

五、综合使用

 1.条件表达np.where

  1. arr = np.array([1, -2, 3, -4])
  2. # 根据条件筛选取数
  3. print(np.where(arr < 0))
  4. # 输出:(array([1, 3], dtype=int64),)
  1. arr = np.array([1, -2, 3, -4])
  2. # 数组中小于0的赋值为0,否则赋值为1
  3. print(np.where(arr < 0, 0, 1))
  4. # 输出:[1 0 1 0]
  1. arr = np.array([1, -2, 3, -4])
  2. # 小于0的元素赋值为0,否则保留原数
  3. print(np.where(arr < 0, 0, arr))
  4. # 输出:[1 0 3 0]

2.数组统计方法

数组统计方法
方法说明
sum,mean求和,求均值
std,var标准差,方差
min,max最值
argmin,argmax最值索引
cumsum所有元素累计求和
cumprod所有元素累计求积

(1)求和

  1. arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
  2. print(np.sum(arr, axis=0))
  3. # 不指定轴,则求全部元素和
  4. print(arr.sum())
  5. # 输出:[ 6 8 10 12]
  6. # 36

(2)最值索引

  1. arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
  2. # 注意,即使是多维数组,返回的也是数字,而不是位置元组
  3. print(np.argmax(arr))
  4. # 输出:7

3.用于布尔型数组的方法

arr.any():是否存在真元素,arr.all()是否全部为真。注意,0和False为假,非0数字和True为真。

空字符串、空列表、None等不能判断。

  1. arr = np.array([1, False, 3, 4])
  2. # 是否全为真
  3. print(arr.all())
  4. # 输出:False

4.排序

  1. arr = np.array([[1, 5, 3, 9], [6, 4, 7, 8]])
  2. print(np.sort(arr, axis=0))
  3. # 输出:[[1 4 3 8]
  4. # [6 5 7 9]]

5.数组的集合操作

数组的集合操作
方法说明
unique(x)返回x中只出现一次的元素数组
intersect1d(x,y)交集
union1d(x,y)并集
in1d(x,y)x的元素是否在y中的布尔数组
setdiff1d(x,y)在x中不在y中的元素
setxor1d(x,y)在x或y中,但不同时存在于两个数组

以上方法的说明已经很明确,就仅以最后一个做示例

  1. arr = np.array([1, 5, 3, 9])
  2. arr2 = np.array([2, 5, 3, 10])
  3. print(np.setxor1d(arr, arr2))
  4. # 输出:[ 1 2 9 10]

6.保存和读取文件

(1)保存文件

  1. arr = np.array([1, 5, 3, 9])
  2. np.save('保存数组.npy', arr)

 记事本打开如下图,数据是以原始二进制格式保存的。

 (2)保存成压缩文件

  1. arr = np.array([1, 2, 3, 4])
  2. arr2 = np.array([5, 6, 7, 8])
  3. # 关键字key1key2是自定义的,用于读取数据
  4. np.savez('保存数组.npz', key1=arr, key2=arr2)

(3)保存到文本文件

  1. arr = np.array([[1, 2, 3, 4], [1, 2, 3, 4]], dtype=int)
  2. # 参数分别表示保存文件名,数组,十进制数格式,逗号分割
  3. np.savetxt('保存数组.txt', arr, fmt="%d", delimiter=',')

 

(3)读取数据

  1. data = np.load('保存数组.npz')
  2. print('数组一的数据为:', data['key1'])
  3. # 输出:数组一的数据为: [1 2 3 4]
  4. # 打开文本文件就是np.loadtxt
  5. data = np.loadtxt('保存数组.txt', delimiter=',')

7.矩阵运算

矩阵运算方法
方法说明
dot矩阵乘法
diagonal返回方阵对角线或将一维数组转成方阵
trace对角线元素之和
det矩阵行列式
inv方阵的逆
qrQR分解
svd奇异值分解
solve解线性方程组Ax=b,A为方阵

(1)矩阵乘法

  1. arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=int)
  2. print('矩阵乘矩阵的转置:\n', arr.dot(arr.T))
  3. # 输出:矩阵乘矩阵的转置:
  4. # [[ 30 70]
  5. # [ 70 174]]

(2)矩阵对角线 

  1. arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [1, 2, 3, 4], [5, 6, 7, 8]], dtype=int)
  2. print(arr)
  3. print('矩阵的对角线:\n', arr.diagonal())
  4. # 输出:[[1 2 3 4]
  5. # [5 6 7 8]
  6. # [1 2 3 4]
  7. # [5 6 7 8]]
  8. # 矩阵乘矩阵的转置:
  9. # [1 6 3 8]

8.产生随机数

np.random的随机函数
方法说明
permutation传入序列则打乱,传入整数则返回打乱的range
shuffle打乱序列
rand[0,1)随机产生一个数,满足均匀分布
randint给定的范围内随机选取整数
randn均值0,方差1的正态分布
binomail二项分布
normal高斯分布
betaBeta分布
chisquare卡方分布
gammaGamma分布
uniform[0, 1)中均匀分布
seed随机种子

(1)打乱序列permutation

  1. data = [1, 2, 3, 4, 5, 6]
  2. arr = np.random.permutation(data)
  3. arr2 = np.random.permutation(6)
  4. print(arr, arr2)
  5. # 输出:[4 3 6 1 2 5] [1 3 2 0 5 4]

(2)给定范围产生一定量随机数

  1. # 1-10之间随机产生2个数
  2. arr = np.random.randint(1, 10, 2)
  3. print(arr)
  4. # 输出:[5 3]

(3)产生一组符合正态分布的数

可以看到,随机产生的这一组数基本满足均值为0,方差为1的正态分布。(数量越大,越接近标准分布)

  1. arr = np.random.randn(1000)
  2. plt.figure(figsize=(10, 8))
  3. plt.hist(arr, bins=20, density=True)
  4. print('均值:{},方差:{}'.format(arr.mean(), arr.std()))
  5. plt.show()
  6. # 输出:均值:-0.0033979715972624175,方差:0.9870680514692056

 (4)关于随机数的一个补充

  1. for i in range(3):
  2. np.random.seed(666)
  3. arr = np.random.random()
  4. print('第{}产生的随机数:{}'.format(i+1, arr))
  5. # 输出:第1产生的随机数:0.7004371218578347
  6. # 第2产生的随机数:0.7004371218578347
  7. # 第3产生的随机数:0.7004371218578347

通过上例可以看出,确定了随机种子,那么每次生成的随机数其实是确定的。也就是说,这里的随机不是真的随机。这个特性在某些过程复现中有用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/1004522
推荐阅读
相关标签
  

闽ICP备14008679号