Numpy 学习日志

Numpy基础

本人的Numpy学习日志,有不对的地方,希望大家能够指出来,相互进步,谢谢

ndarray数组

ndarray 对象是用于存放同类型元素的多维数组。它是一系列同类型数据的集合。

起初以为ndarray数组是矩阵,实际上并不是。ndarray中可以存储多种类型的数据,字符串,时间等。矩阵只能存储数值类型的。

一、ndarray对象的创建(4)

总共学习了4种方法,除了这4种方法之外,还有其他的方法,这里没有罗列出来

  1. np.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称描述
object数组或嵌套的数列
dtype数组元素的数据类型,可选
copy对象是否需要复制,可选
order创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok默认返回一个与基类类型一致的数组
ndmin指定生成数组的最小维度
import numpy as np
array = np.array([1,2,3,4,5])
  1. np.arange(起始值(0), 终止值, 步长(1))
print(np.arange(0, 10, 1)) 
print(np.arange(0, 10))
print(np.arange(10)) 
  1. np.zeros(数组元素个数, dtype=‘类型’)
  2. np.ones(数组元素格式, dtype=‘类型’)
a = np.zeros(10, dtype='int32')
print(a.dtype, a)
a = np.ones(10,dtype='float32') 
print(a.dtype, a) 
a = np.ones(5, dtype='bool')
print(a.dtype, a)

二、ndarray对象属性的基本操作(6)

这里介绍了6种,还有其他的,这里没有罗列出来

  1. 数组的维度:
       array.shape
    既可以展示array的维度,也可以用作修改array的维度
a = np.arange(1, 9) 
print(a.shape, a,sep='\n') 	 

#修改数组对象的维度 		 
a.shape = (2, 4) 
print(a.shape, a, sep='\n') 
a.shape = (2, 2, 2) 
print(a.shape, a, sep='\n')

         array.reshape 也可以用来调整array的维度

a = np.arange(1,9)
a = a.reshape(2,2)
print(a)
  1. 元素的类型:
      array.dtype
b = np.arange(10)
print(b.dtype, b)

这里顺便把Numpy数据类型写一下:
  数据类型对象是用来描述与数组对应的内存区域如何使用

类型名类型表示符字符代码
布尔型bool_b
有符号整数型int8/int16/int32/int64i
无符号整型uint8/uint16/uint32/uint64u
浮点型float16/float32/float64f
复数型complex64/complex128c
字符串型str_ (每个字符32位Unicode编码)S, a

下面是自定义复合数据类型的例子:

import numpy as np

data = [
    ('zs', [90, 85, 80], 16),
    ('ls', [91, 81, 81], 17),
    ('ww', [92, 82, 82], 18)]

# 第一种设置dtype的方式
# 3个Unicode字符,3个32位整型组成的列表,整数
a = np.array(data, dtype='U3, 3int32, int32')
print(a)
# 获取a数组中第一个元素的第一个字段的值
print(a[0]['f0'])
print(a[-1]['f1'])

# 第二种设置dtype的方式
b = np.array(data, dtype={
    'names': ['name', 'scores', 'age'],
    'formats': ['U3', '3int32', 'int32']})
print(b)
print(b[0]['scores'])

# 第三种设置dtype的方式
c = np.array(data, dtype=[
    ('name', 'str_', 2),
    ('scores', 'int32', 3),
    ('age', 'int32', 1)])
print(c)
print(c[2]['name'])

# 第四种设置dtype的方式
# 存储数据时,
# name字段占用8字节,从0字节的位置开始输出
# scores字段占用12字节,从16字节的位置开始输出
# 虽然name字段没有把前16个字节充分利用,但是
# 在内存中字段的位置偏移量是一致的,访问
# 效率将会得到提高。
d = np.array(data, dtype={
    'name': ('U2', 0),
    'scores': ('3int32', 16),
    'age': ('int32', 28)})
print(d)
print(d[0]['name'])

# 测试日期类型数组
e = np.array(['2011', '2012-01-01',
              '2013-01-01 01:01:01',
              '2012-02-01'])
f = e.astype('M8[D]')
print(f.dtype, f)
print(f[2] + 1)
  1. 数组元素个数:
      array.size
b = np.arange(10)
print(b.size)
  1. 数组中每个元素的大小
      array.itemsize
b = np.arange(10)
print(b.itemsize)
  1. 数组的维度
b = np.arange(10)
print(b.ndim)
  1. 二维数组的转置
b = np.arange(10).reshape(2,5)
print(b.T)

三、NumPy 切片和索引(4)

ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。

ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
索引操作

#测试数组索引操作
c = np.arange(1, 28).reshape(3, 3, 3)
print(c)
print(c[0])  # 0页
print(c[0][0])  # 0页 0行
print(c[0][0][0])  # 0页 0行 0列
print(c[0, 0, 0])  # 0页 0行 0列

for i in range(c.shape[0]):
    for j in range(c.shape[1]):
        for k in range(c.shape[2]):
            print(c[i, j, k], end=' ')

切片操作

import numpy as np
a = np.arange(1, 10)
print(a)
print(a[:3])
print(a[3:6])
print(a[6:])
print(a[::-1])
print(a[:-4:-1])
print(a[-4:-7:-1])
print(a[-7::-1])
print(a[::])
print(a[::3])
print(a[1::3])
print(a[2::3])

多维数组的切片

a = np.arange(1, 10)
a = a.reshape(3, 3)
print(a)
print(a[:2, :2])
print(a[:, 2])  # 所有行的最后一列

掩码操作
    掩码操作用起来比较灵活

import numpy as np

a = np.array([43, 70, 34, 76, 34, 57, 23, 45])
print(a)
#a中的每个元素通过与60比较,根据比较结果的值,生成新的ndarry对象b
b = a >= 60
print(b)
#将a中大于等于60的数索引出来,也就是通过b中为True的元素的下标进行索引
print(a[b])
#这里将indices作为一种排序规则,indeices的元素值对应为a中元素的下标,a中的元素将按照indeices提供的顺序进行排序
indices = [1, 7, 6, 5, 4, 3, 2, 0]
print(a[indices])

# 输出100以内3与7的倍数
b = np.arange(100)
#这里不能使用and 或者 or,得使用 位运算 或者 any,all
mask = (b % 3 == 0) & (b % 7 == 0)
print(b[mask])

四、多维数组的组合与拆分(4)

  1. 普通的方向上的操作:
    1. 垂直方向的操作:
      #在垂直方向a与b摞起来
      np.vstack((a, b))
      #把c数组在垂直方向拆成2个
      np.vsplit(c, 2)
      
    2. 水平方向的操作:
      #在水平方向a与b并起来
      np.hstack((a, b))
      #把c数组在水平方向拆成2个
      np.hsplit(c, 2)
      
    3. 深度方向的操作:
      #在深度方向a与b并起来
      np.dstack((a, b))
      #把c数组在深度方向拆成2个
      np.dsplit(c, 2)
      
  2. 通用方法:
    # 实现a与b数组的组合操作
    # axis:轴向
    # 如果待组合数组都是二维数组
    # axis:0 垂直方向组合
    # axis:1 水平方向组合
    # 如果待组合数组都是三维数组
    # axis:0 垂直方向组合
    # axis:1 水平方向组合
    # axis:2 深度方向组合
    np.concatenate((a, b), axis=0)
    # 把c数组拆成2分  axis为轴向
    np.split(c, 2, axis=0)
    
  3. 长度不等的数组的组合:
    #长度不等的数组的组合
    a = np.array([1, 2, 3, 4, 5])
    b = np.array([6, 7, 8, 9])
    #把b补成5个元素, 头部补0个,尾部补1个,
    #新增元素的默认值为-1
    b = np.pad(b, pad_width=(0, 1), mode='constant',constant_values=-1)
    print(b)
    
  4. 简单的一维数组的组合方案:
# 把a与b两个一维数组摞在一起成两行
np.row_stack((a, b))
# 把a与b两个一维数组组合在一起成两列
np.column_stack((a, b))

五、加载文件

    np.loadtxt( )

#a,b,c将读取出来的列添加上索引名称,相当于表格的字段
a,b,c = np.loadtxt(
					'../data/aapl.csv',		# 文本路径
				    delimiter=',',			# 列之间的分隔符
				    usecols=(0,1,2),		# 读取哪些列
				    unpack=False,			# 是否拆包 False将会返回二维数组
				    dtype="U10, U10, f8",	# 元素的类型
				    converters={1, func}	# 转换器函数字典
)

六、统计学方面的

  1. 算数平均数
# 1.
m = np.mean(array)
# 2.
m = array.mean()
  1. 加权平均数
# a: 原始样本数组
# b: 与原始样本数组相对应的权重数组
np.average(a, weights=b)
  1. 最值
np.max(a)	# 返回一组数据的最大值
np.min(a)	# 返回一组数据的最小值
np.ptp(a)	# 返回一组数据的极差 (max-min)

np.argmax(a)	# 返回一组数据最大值的下标
np.argmin(a) 	# 返回一组数据最小值的下标

# 将两个同维数组中对应位置的元素进行比较,把最大的保留。返回新数组
np.maximum(a, b)
# 将两个同维数组中对应位置的元素进行比较,把最小的保留。返回新数组
np.minimum(a, b)
  1. 中位数
a = [..排序过的数组..]
np.median(a)
  1. 标准差
# 求array数组的总体标准差
np.std(array)
# 求array数组的样本标准差,分母的修正值:n-1
np.std(array, ddof=1)
  1. 卷积运算
# a: 原数组
# b: 卷积核数组
# 卷积类型: 
# 	'valid'	有效卷积
# 	'same'	同维卷积
# 	'full'	完全卷积
np.convole(a, b, 卷积类型)
  1. 协方差和相关系数
    协方差:
    np.cov(a,b)
    相关系数矩阵
    np.corrcoef(a, b)
    在这里插入图片描述

七、线性代数

  1. 线性预测
    在这里插入图片描述
    案例:基于线性预测,预测下一天的收盘价。预测结果不准,只是做一个测试。
# 整理三元一次方程组, 实现线性预测
N = 5
pred_prices = np.zeros(
    closing_prices.size - 2 * N + 1)
# 把每一个预测值都求出来
for i in range(pred_prices.size):
    # 整理矩阵a与矩阵b,使用lstsq方法求出x
    a = np.zeros((N, N))
    for j in range(N):
        a[j, ] = closing_prices[i + j:i + j + N]
    b = closing_prices[i + N:i + N * 2]
    x = np.linalg.lstsq(a, b)[0]
    # b与x执行点积运算
    pred_prices[i] = b.dot(x)

# 画出预测股价曲线
mp.plot(dates[2 * N:], pred_prices[:-1],
        'o-', color='orangered',
        linewidth=2, label='Predict Line')

print(pred_prices[-1])
  1. 线性拟合
    在这里插入图片描述
# 计算所有的趋势点
trend_points = (
    highest_prices + lowest_prices +
    closing_prices) / 3

mp.plot(dates, trend_points, color='dodgerblue',
        linewidth=2, linestyle=':',
        label='Trend Points')
# 一组x坐标
days = dates.astype('M8[D]').astype(int)
a = np.column_stack((days, np.ones(days.size)))
b = trend_points
# 通过a与b求x
x = np.linalg.lstsq(a, b)[0]
# 求该直线的所有x对应的函数值
y = x[0] * days + x[1]
mp.plot(dates, y, color='orangered',
        linestyle='--', linewidth=3,
        label='Trend Line')

# 绘制顶部压力线  底部支撑线
spreads = highest_prices - lowest_prices
resistance_points = y + spreads
support_points = y - spreads

mp.plot(dates, resistance_points,
        color='red', linewidth=2,
        label='Resistance Line')
mp.plot(dates, support_points,
        color='limegreen', linewidth=2,
        label='Support Line')
  1. 多项式拟合
    多项式的一般形式:
    y = p 0 x n + p 1 x n − 1 + p 2 x n − 2 + . . . + p n y = p_0x^n + p_1x^{n-1} + p_2x^{n-2} + ... + p_n y=p0xn+p1xn1+p2xn2+...+pn
    多项式拟合的目的是为了找到一组p0~pn , 使得拟合方程尽可能的域实际样本数据相符合(误差最小)
# 根据一组离散样本,给出最高次幂,求出拟合多项式结果的系数数组。
# P = [p0, p1 ... pn]
P = np.polyfit(x, y, 最高次幂)

# 给出自变量x,该方法将把x代入多项式,求出函数值。
Y = np.polyval(P, x) 

# 求多项式函数的导函数  (Q = [q1, q2 ... qm])
Q = np.polyder(P)

# 求多项式的根(y等于0是x的取值)
x = np.roots(P)
  1. 矩阵

    1. 矩阵对象的创建
      numpy.matrix(ary, copy=True)
      numpy.mat(任何可以被解释为矩阵的二维容器)
    2. 矩阵的乘法
    a = np.mat('1 2 3; 5 6 4; 3 4 5')
    b = np.mat('1 2 3; 5 6 4; 3 4 5')
    print(a * b)
    print(a.dot(b))
    
    1. 矩阵的逆
      A.I
      np.linalg.inv(A)
    2. 斐波那契数列
    A = np.mat('1 1; 1 0')
    n = 35
    for i in range(1, n + 1):
    	print((A**i)[0, 1])
    
    1. 加法通用函数
    a = np.arange(1, 10)
    b = np.arange(1, 10)
    np.add(a, b)			# a与b两数组对应位置元素相加
    np.add.reduce(a)		# a所有元素的累加和
    np.add.accumulate(a)	# 返回累加和的过程数组
    np.add.outer([10,20,30], a)	# 列表与a数组的外和
    
    1. 乘法通用函数
    ndarray.prod()		# 返回a数组中所有元素累乘的结果
    np.prod(a)
    ndarray.cumprod()	# 返回a数组中所有元素累乘的过程
    np.cumprod(a)
    np.outer([10, 20, 30], a)	# 外积
    
    1. 除法通用函数
    np.true_divide(a, b) 	#  a除以b
    np.divide(a, b)			#  等价于上一个API
    np.floor_divide(a, b)	#  地板除
    np.ceil(a / b)			#  取天花板整数
    np.trunc(a / b)			#  取截断整数
    np.round(a / b)
    
    1. 广义逆矩阵
      如果一个方阵A与另一个方阵B的乘积是一个单位矩阵,A与B互为逆矩阵,
      将以上有关逆矩阵的定义推广到非方阵,则成为广义逆矩阵。
    import numpy as np
    a = np.mat('11 12 11 14;20 21 21 23;19 18 11 16')
    print(a)
    b = a.I
    #b = np.linalg.inv(a)
    print(b)
    print(a * b)
    
    1. 特征值与特征向量
      对于n阶方阵A,如果存在数a与非零n维列向量x,使得Ax=ax, 则称a是矩阵A的一个特征值,x是矩阵A属于特 征值a的特征向量。
    #已知n阶方阵A, 求特征值与特征向量
    #eigvals:特征值数组
    #eigvecs:对应的特征向量数组
    eigvals, eigvecs = np.linalg.eig(A)
    # 已知特征值与特征向量,求方阵
    S = eigvecs * np.diag(eigvals) * eigvecs.I
    

    案例

    import numpy as np
    
    A = np.mat('1 6 5; 9 7 3; 1 5 6')
    print(A)
    # 特征值提取
    eigvals, eigvecs = np.linalg.eig(A)
    print(eigvals, eigvecs, sep='\n')
    
    # 通过特征值与特征向量, 求方阵
    S = np.mat(eigvecs) * np.mat(np.diag(eigvals))* np.mat(eigvecs).I
    print(S)
    

    案例:读取图片的亮度矩阵,提取特征值与特征向量,保留部分特征值,重新生成新的亮度矩阵,绘制图片。

    import numpy as np
    import scipy.misc as sm
    import matplotlib.pyplot as mp
    
    img = sm.imread('../da_data/lily.jpg', True)
    # 特征值提取
    eigvals, eigvecs = np.linalg.eig(img)
    # 把靠后的特征值与特征向量置为0(抹掉特征)
    eigvals[50:] = 0
    # 重新生成新的图片
    img2 = np.mat(eigvecs) * np.mat(np.diag(eigvals)) *	np.mat(eigvecs).I
    img2 = img2.real
    mp.figure('Image Features')
    mp.subplot(1, 2, 1)
    mp.xticks([])
    mp.yticks([])
    mp.imshow(img, cmap='gray')
    mp.subplot(1, 2, 2)
    mp.xticks([])
    mp.yticks([])
    mp.imshow(img2, cmap='gray')
    mp.tight_layout()
    mp.show()
    

八、随机数模块

  1. 二项分布
    二项分布就是重复n次独立事件的伯努利实验。在每次实验中只有两种可能的结果,而且两种结果发生与否相互对立,相互独立,事件发生与否的概率在每一次独立实验中都保持不变。
# 产生size个随机数, 每个随机数来自n次尝试中成功的次数
# 其中每次尝试成功的概率为p。
np.random.binomial(n, p, size)
np.random.binomial(100, 0.5, 100)
  1. 超几何分布(hypergeometric)
# 产生size个随机数
# 每个随机数为在总样本中随机抽取nsample个样本后,好样本的个数
# 总样本由ngood个好样本和nbad个坏样本组成
np.random.hypergeometric(ngood, nobad, nsample, size)
np.random.hypergeometric(7, 3, 3, 1)
  1. 正态分布
# 产生size个随机数,服从标准正态分布(期望=0,标准差=1)
np.random.normal(size)
# 产生size个随机数,服从正态分布(期望=1,标准差=10)
np.random.normal(loc=1, scale=10, size)

九、其他

np.sign(原数组):
        np.sign()函数可以把样本数组编程对应的符号数组,正数变为1,负数变为-1,0还是0。
np.diff(原数组):
        用来将数据进行某种移动之后与原数据进行比较得出的差异数据
np.piecewise(原数组,条件序列,取值序列):
        针对原数组的每个元素做条件判断,取相应的值
        条件序列:[array<60, array>=60]
        取值序列:[-1, 1]
np.vectorize(原函数)
        可以把处理标量的函数矢量化,返回一个新的函数(矢量函数),该矢量函数可以直接处理ndarray数组。
np.frompyfunc(原函数,参数数量,返回结果数量)
        与vectorize具有相同的功能

未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值