Numpy之ndarray基础篇


NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。是在学习机器学习、深度学习之前应该掌握的一个非常基本且实用的Python库。

Numpy官方文档

初见ndarray对象

ndarray基本概念

ndarray是numpy库中的一个处于核心地位的数据结构,全称为N-Dimension Array,从字面上就表明了它是一个N维数组。要注意的是,ndarray是同质的,就是说其中的元素都必须是同一种数据类型(PS: python中的list列表是异质的)
ndarray实例化后,包含一些基本属性,如shape、ndim、size、dtype等。例如现在有一个3行5列的矩阵(ndarray)如下:

array([[ 0,  1,  2,  3,  4],
	   [ 5,  6,  7,  8,  9],
	   [10, 11, 12, 13, 14]])

那么该ndarray的shape值为(3,5)(元组类型,表示3行5列)
ndim为2(表示矩阵维度为2)
size为15(矩阵总共有15个元素)
dtype为int32(因为矩阵中的元素都是32位整数)

# 导入numpy并取别名为np
import numpy as np
# 构造ndarray
a = np.arange(15).reshape(3, 5)
# 打印a的shape,ndim,size,dtype
print(a.shape)
print(a.ndim)
print(a.size)
print(a.dtype)

ndarray对象实例化的方法

实例化ndarray的最常用的方法就是使用array函数,用list对象作为参数传递,返回以list中的内容为初始值的ndarray对象:

import numpy as np
# 使用列表作为初始值,实例化ndarray对象a
a = np.array([2,3,4])
# 打印ndarray对象a
print(a)

在这里插入图片描述
除了array以外比较常用的实例化函数还有zeros、ones、empty,这三个函数的参数都是表示返回ndarray对象形状的元组

zeros返回一个全为0的ndarray对象:

import numpy as np
# 实例化ndarray对象a,a是一个3行4列的矩阵,矩阵中元素全为0
a = np.zeros((3, 4))
# 打印ndarray对象a
print(a)

在这里插入图片描述
ones与上类似,返回一个全为1的ndarray对象:

import numpy as np
# 实例化ndarray对象a,a是一个3行4列的矩阵,矩阵中元素全为1
a = np.ones((3, 4))
# 打印ndarray对象a
print(a)

在这里插入图片描述
empty则是返回一个元素的值没有经过初始化的ndarray:

import numpy as np
# 实例化ndarray对象a,a是一个2行3列的矩阵,矩阵中元素全为随机值
a = np.empty((2, 3)) 
# 打印ndarray对象a
print(a)

在这里插入图片描述
还有两个比较常用的生成一维数组的函数arange、linspace:

arange参数与range类似,只不过生成的是一维ndarray对象:
在这里插入图片描述
linspace用于生成等间隔的一组数,前两个参数是生成的区间,第三个参数是生成的数的个数
在这里插入图片描述

ndarray形状操作

ndarray的数组与一般的数组列表的一个不同之处就是它可以变换形状,这使得一些数据处理的操作变得尤为方便。最直接粗暴的变换方法就是修改shape属性的值

import numpy as np
a = np.zeros((3, 4))
# 直接修改shape属性
a.shape = [4, 3]

在这里插入图片描述
但这样做不符合编程规范,更优雅的方法是使用ndarray对象提供的方法reshape。该方法(及其他大部分方法都)有两种调用方式,一种是直接作为函数调用,参数为ndarray对象及形状元组;另一种是作为ndarray实例的成员函数来调用。

面向对象风格

import numpy as np
a = np.zeros((3, 4))
# 调用a的成员函数reshape将3行4列改成4行3列
a = a.reshape((4, 3))

面向过程风格

import numpy as np
a = np.zeros((3, 4))
# 调用reshape函数将a变形成4行3列
a = np.reshape(a, (4, 3))

另外,reshape有一个非常方便的功能就是可以自动判断某一维上的长度。例如要将一个6行8列的二维数组变化成2列,那么只要在未知的维上传入参数-1,reshape就会自动得出变化后的数组应为24行

import numpy as np
a = np.zeros((6, 8))
# 行的维度上填-1,会让numpy自己去推算出行的数量,很明显,行的数量应该是24
a = a.reshape((-1, 2))

在这里插入图片描述
不过最多只有一个维度能填-1,如果超过一个维度是-1就会抛出异常
在这里插入图片描述

PS:要注意reshape并不会改变原ndarray的形状,而只是返回变化后的ndarray对象,所以需要将其赋值给原变量。

如果想要直接改变原ndarray的形状,除了之前的直接修改shape属性,可以使用resize方法:

import numpy as np
a = np.zeros((3, 4))
# 将a从3行4列的二维数组变成一个有12个元素的一维数组
a.resize(12)

ndarray基础操作

作为数据处理的利器,ndarray自然提供了常用的数学的处理功能。

基本运算

ndarray可以直接和基本的数字类型变量运算,返回该运算作用到数组中所有元素上的结果。

import numpy as np
a = np.array([0, 1, 2, 3])
# a中的所有元素都加2,结果为[2, 3, 4, 5]
b = a + 2
# a中的所有元素都减2,结果为[-2, -1, 0, 1]
c = a - 2
# a中的所有元素都乘以2,结果为[0, 2, 4, 6]
d = a * 2
# a中的所有元素都平方,结果为[0, 1, 4, 9]
e = a ** 2
# a中的所有元素都除以2,结果为[0, 0.5, 1, 1.5]
f = a / 2
# a中的所有元素都与2比,结果为[True, True, False, False]
g = a < 2

ndarray与ndarray之间也可以运算,返回两个数组中对应位置元素相互作用的结果。

import numpy as np
a = np.array([[0, 1], [2, 3]])
b = np.array([[1, 1], [3, 2]])
# a与b逐个元素相加,结果为[[1, 2], [5, 5]]
c = a + b
# a与b逐个元素相减,结果为[[-1, 0], [-1, 1]]
d = a - b
# a与b逐个元素相乘,结果为[[0, 1], [6, 6]]
e = a * b
# a的逐个元素除以b的逐个元素,结果为[[0., 1.], [0.66666667, 1.5]]
f = a / b
# a与b逐个元素做幂运算,结果为[[0, 1], [8, 9]]
g = a ** b
# a与b逐个元素相比较,结果为[[True, False], [True, False]]
h = a < b

PS:当运算的两个ndarray形状不同时,会触发Numpy的广播(broadcasting)机制尝试将两个ndarray自动拓展成相同形状。关于广播机制将在下一篇文章中讲解。

上述运算都是逐个元素进行运算,如果想要进行数学中的矩阵乘这种运算,可以使用Numpy提供的运算符@或函数dot。

import numpy as np
A = np.array([[1, 1], [0, 1]])
B = np.array([[2, 0], [3, 4]])
# @表示矩阵乘法,矩阵A乘以矩阵B,结果为[[5, 4], [3, 4]]
print(A @ B)
# 面向对象风格,矩阵A乘以矩阵B,结果为[[5, 4], [3, 4]]
print(A.dot(B))
# 面向过程风格,矩阵A乘以矩阵B,结果为[[5, 4], [3, 4]]
print(np.dot(A, B))

简单统计

在一般的数组中进行统计需要手动用循环遍历整个数组,而ndarray为了解放程序员们的双手,提供了sum、min、max、argmax、argmin等方法实现简单的统计功能。

import numpy as np
a = np.array([[-1, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 13]])
# 计算a中所有元素的和,结果为67
print(a.sum())
# 找出a中最大的元素,结果为13
print(a.max())
# 找出a中最小的元素,结果为-1
print(a.min())
# 找出a中最大元素在a中的位置,由于a中有12个元素,位置从0开始计,所以结果为11
print(a.argmax())
# 找出a中最小元素在a中位置,结果为0
print(a.argmin())

当需要按某一个方向/轴来进行统计时,可以向这些方法传入axis参数。例如有一个学生成绩表如下,要统计出每一名学生的总分:

姓名语文数学英语物理化学政治历史
张三9011210484897780
李四10510911481818792
王五931039779758079

用ndarray存储如下

a=np.array([[  90, 112, 104,  84,  89,  77,  80],
			[ 105, 109, 114,  81,  81,  87,  92],
			[  93, 103,  97,  79,  75,  80,  79]])

那么要做的就是统计每一行的和,沿着横轴把元素相加,axis为所沿轴的序号
在这里插入图片描述
在这里插入图片描述
其余方法以及更高维的数组同理。

PS:当没有修改axis时,axis的值默认为None。意思是在统计时会把ndarray对象中所有的元素都考虑在内。

随机数生成

简单随机数生成

NumPy的random模块下提供了许多生成随机数的函数,如果对于随机数的概率分布没有什么要求,则通常可以使用random_sample、choice、randint等函数来实现生成随机数的功能。这些函数的功能都和Python标准库random 中的类似,只不过是作用在ndarray对象上或返回ndarray。

random_sample:用于生成区间为 [ 0 , 1 ] [0,1] [0,1]的随机数,参数size为生成ndarray的形状。

import numpy as np
'''
结果可能为[[0.32343809, 0.38736262, 0.42413616]
          [0.86190206, 0.27183736, 0.12824812]]
'''
print(np.random.random_sample(size=[2, 3]))

choice:从给定范围的数字中随机挑选生成ndarray。参数a是一维数组或整数,给定一维数组时生成ndarray中的元素将从中随机选取,给定整数时则从np.arange(a)中随机选取;参数size为生成ndarray形状;参数replace决定是否能有重复元素,默认值为True即允许重复。

import numpy as np
'''
模拟掷5次骰子
掷骰子时可能出现的点数为1, 2, 3, 4, 5, 6,所以a=[1,2,3,4,5,6]
模拟5次掷骰子所以size=5
骰子点数可以重复出现所以replace=True
结果可能为 [4 3 1 4 3]
'''
print(np.random.choice(a=[1, 2, 3, 4, 5, 6], size=5,replace=True))

PS:当生成ndarray中元素数量多于a且replace=False时会抛出异常ValueError: Cannot take a larger sample than population when ‘replace=False’

randint:生成选定区间内的整数随机选取产生的ndarray。参数low、high为区间的上下限,区间为半开半闭区间 [ l o w , h i g h ) [low,high) [low,high);参数size为生成数组形状。

import numpy as np
'''
模拟掷5次骰子
掷骰子时可能出现的点数为1, 2, 3, 4, 5, 6,所以low=1,high=7
模拟5此掷骰子所以size=5
结果可能为 [6, 4, 3, 1, 3]
'''
print(np.random.randint(low=1, high=7, size=5)

概率分布随机数生成

如果对于产生的随机数的概率分布有特别要求,NumPy同样提供了从指定的概率分布中采样得到的随机值的接口。在这里主要介绍正态分布。
正态分布又称为高斯分布,其分布图形如下:
在这里插入图片描述
要根据正态分布产生随机数,可以使用normal函数。该函数的参数有loc、scale、size,分别是正态分布的均值、方差和生成数组的形状。默认情况下loc=0,scale=1,即标准正态分布。
在这里插入图片描述

随机种子

众所周知计算机无法产生真正的随机数,所有计算机产生的随机数本质都是伪随机数,其结果由随机种子决定。Numpy中手动设定随机种子的方法就是使用seed函数,其参数为seed。

import numpy as np
# 设置随机种子为233
np.random.seed(seed=233)
data = [1, 2, 3, 4]
# 随机从data中挑选数字,结果为4
print(np.random.choice(data))
# 随机从data中挑选数字,结果为4
print(np.random.choice(data))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值