文章目录
Python原生语法与Numpy对比
求数组元素的和:
(1)使用Python原生list:
def python_sum(n):
""" Python实现数组的加法
@param n:数组的长度
"""
a = [i**2 for i in range(n)]
b = [i**3 for i in range(n)]
c = []
for i in range(n):
c.append(a[i] + b[i])
return c
(2)使用Numpy:
def numpy_sum(n):
""" numpy实现数组的加法
@param n:数组的长度
"""
a = np.arange(n) ** 2
b = np.arange(n) ** 3
return a+b
从上面的代码中可以看到,要求数组中各元素的和,如果用原生List,必须使用循环。而Numpy数组可以直接用运算符。
此外,Numpy的执行速度也比原生Python List快很多。
Numpy的核心array对象以及创建array的方法
创建array的方法:
(1)从Python的列表List和嵌套列表创建array:
import numpy as np
# 创建一个一维数组,也就是Python的单元素List
x = np.array([1,2,3,4,5,6,7,8])
# 创建一个二维数组,也就是Python的嵌套List
X = np.array(
[
[1,2,3,4],
[5,6,7,8]
]
)
(2)使用预定函数的arange、ones/ones_like、zeros/zeros_like、empty/empty_like、full/full_like、eye等函数创建:
#【1】arange函数:arange([start,] stop[, step,], dtype=None)
np.arange(10) #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(2, 10, 2) #array([2, 4, 6, 8])
# 【2】ones函数:np.ones(shape, dtype=None, order='C')
#shape : int or tuple of ints Shape of the new array, e.g., (2, 3) or 2
np.ones(10)#array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
np.ones((2,3))
#array([[1., 1., 1.],
# [1., 1., 1.]])
# 【3】ones_like函数:ones_like(a, dtype=float, order='C')
np.ones_like(x)
np.ones_like(X)
# 【4】empty函数:empty(shape, dtype=float, order='C')
#注意:数据是未初始化的,里面的值可能是随机值不要用
np.empty(10)#array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.empty((2,4))
# 【5】full函数:np.full(shape, fill_value, dtype=None, order='C')
# 创建指定值的数组
np.full(10, 666)
np.full((2,4), 333)
(3)生成随机数的np.random模块构建:
#【1】设定随机种子,每次生成的随机数相同
np.random.seed(666)
#【2】rand(d0, d1, ..., dn)
#返回数据在[0,1)之间,具有均匀分布
np.random.rand(5)#array([0.70043712, 0.84418664, 0.67651434, 0.72785806, 0.95145796])
np.random.rand(3, 4)
np.random.rand(2, 3, 4)
#【3】uniform([low, high, size])
#在[low, high)之间生成均匀分布的数字
np.random.uniform(1, 10, 10)
np.random.uniform(1, 10, (3,4))
#【4】randn(d0, d1, ..., dn)
#返回数据具有标准正态分布(均值0,方差1)
np.random.randn(5)
np.random.randn(3, 4)
np.random.randn(2, 3, 4)
#【5】normal([loc, scale, size])
#按照平均值loc和方差scale生成高斯分布的数字
np.random.normal(1, 10, 10)
np.random.normal(1, 10, (3,4))
#【6】randint(low[, high, size, dtype])
#生成随机整数,包含low,不包含high
#如果high不指定,则从[0, low)中生成数字
np.random.randint(3) # 2
np.random.randint(1, 10)# 1
np.random.randint(10, 30, size=(5,))
np.random.randint(10, 30, size=(2,3,4))
#【7】random([size])
#生成[0.0, 1.0)的随机数
np.random.random(5)
np.random.random(size=(3,4))
np.random.random(size=(2,3,4))
#【8】choice(a[, size, replace, p])
#a是一维数组,从它里面生成随机结果
np.random.choice(5, 3)# 这时候,a是数字,则从range(5)中生成,size为3
#array([4, 2, 4])
np.random.choice(5, (2,3))## 这时候,a是数组,从里面随机取出数字
#array([3, 9, 6])
np.random.choice([2, 3, 6, 7, 9], (2,3))
#array([[7, 9, 2],
# [6, 9, 6]])
#【9】shuffle(x) 把一个数组x进行随机排列
a = np.arange(10)
np.random.shuffle(a)#array([7, 2, 3, 6, 1, 9, 8, 4, 0, 5])
a = np.arange(20).reshape(4,5)
# 如果数组是多维的,则只会在第一维度打散数据
np.random.shuffle(a)
#【10】permutation(x) 把一个数组x进行随机排列,或者数字的全排列
# 这时候,生成range(10)的随机排列
np.random.permutation(10)#array([1, 5, 3, 0, 2, 4, 7, 9, 6, 8])
# 这时候,在第一维度进行打散
arr = np.arange(9).reshape((3, 3))
np.random.permutation(arr)# 注意,这里不会更改原来的arr,会返回一个新的copy
# 【11】linspace(start,stop,num)
x = np.linspace(-10, 10, 100) #从-10到10生成100个数
获取array本身的属性:
标量张量有0 个轴(ndim == 0)。张量轴的个数也叫作阶(rank)。
import Numpy as np
x=np.array([1,2,3])
x.shape #返回一个元组,表示array的维度
x.ndim #一个数字,表示array的维度的数目
x.size #一个数字,表示array中所有数据元素的数目
x.dtype #array中元素的数据类型
array本身支持的大量操作和函数:
A = np.arange(10).reshape(2,5)
A+1 #加法
A*3 #乘法
np.sin(A) #三角函数
np.exp(A) #指数函数
Numpy对数组按索引查询
基础索引
import numpy as np
# 一维向量
x = np.arange(10)
# 二维向量,一般用大写字母
X = np.arange(20).reshape(4,5)
#【1】一维数组
print(x[2], x[5], x[-1])
x[2:4]
x[2:-1]
x[-3:]
#【2】二维数组
# A. 分别用行坐标、列坐标,实现行列筛选
X[0, 0] ## X[0][0] 用逗号的写法更简便
X[-1, 2]
# B. 可以省略后续索引值,返回的数据是降低一个维度的数组
X[2] # 这里的2,其实是要筛选第2行
X[:-1]# 筛选多行
X[:2, 2:4]# 筛选多行,然后筛选多列
X[:, 2]# 筛选所有行,然后筛选多列
#【3】切片的修改会修改原数组
X[:1, :2] = 666
神奇索引
用整数数组进行的索引,叫神奇索引。
#【1】一维数组:新数组和索引数组形状相同
x = np.arange(10) #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[[3,4,7]] #array([3, 4, 7])
indexs = np.array([[0, 2], [1, 3]])
x[indexs]
#array([[0, 2],
# [1, 3]])
#【2】一维数组实例:获取数组中最大的前N个数字
arr[arr.argsort()[-3:]] #argsort函数返回排序后的数组索引
#【3】二维数组
X = np.arange(20).reshape(4, 5)
X[[0, 2]]# 筛选多行,列可以省略
X[:, [0,2,3]]# 筛选多列,行不能省略
X[[0, 2, 3], [1, 3, 4]]# 同时指定行列-列表
# 返回的是[(0,1), (2,3), (3,4)]位置的数字
布尔索引
#【1】一维数组
x>5 #array([False, False, False, False, False, False, True, True, True, True])
x[x>5] #array([6, 7, 8, 9])。即返回布尔索引数组中为True的值。
#【2】二维数组
X = np.arange(20).reshape(4,5)
X[X>5]# X>5的boolean数组,既有行,又有列
# 因此返回的是(行,列)一维结果
#array([ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
#【3】实例:把第3列大于5的行筛选出来
X[:, 3]# 第3列:array([ 3, 8, 13, 18])
X[:, 3]>5 #第3列的值大于5的行:array([False, True, True, True])
X[X[:, 3]>5]# 这里是按照行进行的筛选
#【4】条件组合
x = np.arange(10)
condition = (x%2==0) | (x>7)# 注意,每个条件都得加小括号
x[condition]
Numpy的数学统计函数
常见统计函数
import numpy as np
arr = np.arange(12).reshape(3,4)
np.sum(arr) #所有元素的和
np.prod(arr) #所有元素的乘积
np.cumsum(arr) #元素的累积加和
np.cumprod(arr) #元素的累积乘积
np.min(arr) #最小值
np.max(arr) #最大值
np.percentile(arr, [25, 50, 75]) #0-100百分位数
np.quantile(arr, [0.25, 0.5, 0.75]) #0-1分位数
np.median(arr) #中位数
np.mean(arr) #平均值
np.std(arr) #标准差
np.var(arr) #方差
weights = np.random.rand(*arr.shape) #weights的shape需要和arr一样
np.average(arr, weights=weights) #加权平均,参数可以指定weights
Numpy的axis参数的用途
axis=0代表行、axis=1代表列。对于sum/mean/media等聚合函数:
- 理解1:axis=0代表把行消解掉,axis=1代表把列消解掉
- 理解2:axis=0代表跨行计算,axis=1代表跨列计算
arr
#array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
arr.sum(axis=0) #把行消解掉,得到每列的和
#array([12, 15, 18, 21])
arr.sum(axis=1) #把列消解掉,得到每行的和
#array([ 6, 22, 38])
实例:机器学习将数据进行标准化
arr如果对应到现实世界的一种解释:
- 行:每行对应一个样本数据
- 列:每列代表样本的一个特征
数据标准化:
- 对于机器学习、神经网络来说,不同列的量纲应该相同,训练收敛的更快;
- 比如商品的价格是0到100元、销量是1万到10万个,这俩数字没有可比性,因此需要先都做标准化;
- 不同列代表不同的特征,因此需要axis=0做计算
- 标准化一般使用 公式进行
# 计算每列的均值
mean = np.mean(arr, axis=0)
# 计算每列的方差
std = np.std(arr, axis=0)
# 计算分子,注意每行都会分别减去[4., 5., 6., 7.],这叫做numpy的广播
fenzi = arr-mean
result = fenzi/std
#【简便写法】
result = (arr - np.mean(arr,axis=0)) / np.std(arr,axis=0)
Numpy怎样给数组增加一个维度
np.newaxis:
关键字,使用索引的语法给数组添加维度。
import numpy as np
arr = np.arange(5)
np.newaxis == None #True
#【1】给一维向量增加一个行维度
arr.shape #(5,)
arr[np.newaxis, :] #(1, 5)
#【2】给一维向量增加一个列维度
arr.shape #(5,)
arr[:, np.newaxis] #(5, 1)
np.expand_dims方法:
np.expand_dims方法实现的效果,和np.newaxis关键字是一模一样的。
#【1】给一维向量增加一个行维度
arr.shape #(5,)
np.expand_dims(arr, axis=0) #(1, 5)
#【2】给一维向量增加一个列维度
arr.shape #(5,)
np.expand_dims(arr, axis=1) #(5, 1)
np.reshape方法:
#【1】给一维向量增加一个行维度
arr.shape #(5,)
np.reshape(arr, (1, 5)) #(1, 5)
np.reshape(arr, (1, -1)) #(1, 5)
#【2】给一维向量增加一个列维度
arr.shape #(5,)
np.reshape(arr, (-1, 1)) #(5, 1)