Numpy

系列文章目录

第一章 python数据挖掘基础环境安装和使用
第二章 Matplotlib


文章目录

  • 系列文章目录
  • 一、介绍
    • ndarray
    • 优势
    • 属性
    • 使用
  • 二、ndarray的形状
  • 三、ndarray的类型
  • 四、创建数组的时候指定类型
  • 五、基本操作
    • 生成数组的方法
      • 生成0和1的数组
      • 从现有数组生成
      • 生成固定范围的数组
      • 生成随机数组
    • 案例:随机生成8只股票2周的交易日涨幅数据
      • 数组的索引、切片
      • 形状修改
      • 类型修改
        • ndarray序列化到本地
      • 数组的去重
  • 六、ndarray运算
    • 6.1 逻辑运算
      • 运算符
      • 通用判断函数
      • 三元运算符
    • 6.2 统计运算
      • 统计指标函数
      • 返回最大值、最小值的位置
    • 6.3 数组间运算
      • 数组与数的运算
      • 数组与数组的运算
        • 广播机制
      • 矩阵运算
        • 矩阵乘法运算
    • 6.4 合并、分割
    • 6.5 IO 操作与数据处理
      • Numpy读取数据


一、介绍

Numpy 高效的运算工具

  • num = numerical 数值化的
  • py = python

Numpy (Numerical Python) 是一个开源的 Python 科学计算库,用于快速处理任意维度的数组。

Numpy 支持常见的数组和矩阵操作。对于同样的数值计算任务,使用 Numpy 比直接使用 Python 要简洁的多。

Numpy 使用 ndarray 对象来处理多维数组,该对象是一个快速而灵活的大数据容器。
Numpy_第1张图片

ndarray

  • n = 任意个
  • d = dimension 维度
  • array = 数组

NumPy 提供了一个 N 维数组类型 ndarray,它描述了相同类型的"items"的集合

优势

  1. 存储风格
    • ndarray - 相同类型数据 - 通用性不强
    • list - 不同类型 - 通用性很强
  2. 并行化运算
    • ndarray 支持向量化运算
  3. 底层语言
    • Python多线程其实并不是真正的多线程,是受到GIL的限制的, 由于Numpy 底层使用 C 语言编写,内部解除了 GIL(全局解释器锁),当如果我们用多线程的时候,它也是支持多线程的,其对数组的操作速度不受 Python 解释器的限制,效率远高于纯 Python 代码。

属性

属性名字 属性解释
ndarray.shape 数组维度的元组, 形状
ndarray.ndim 数组维数, 维度
ndarray.size 数组中的元素数量
ndarray.itemsize 一个数组元素的长度(字节)
ndarray.dtype 数组元素的类型

在创建 ndarray 的时候,如果没有指定类型,默认:整数 int64/int32 浮点数 float64/float32

使用

import numpy as np
score = np.array([[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69],
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]])
print(type(score)) # 
print(score.shape) # (8, 5)
print(score.dtype) # int32

Numpy_第2张图片

二、ndarray的形状

a = np.array([[1,2,3],[4,5,6]])
b = np.array([1,2,3,4])
c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]])

a # 形状 (2,3) 2行3列   二维数组
b # (4,) 一维数组
c # (2,2,3) 三维数组

Numpy_第3张图片
ndarray.shape,返回一个元组, 里面 几个数字代表几个维度

三、ndarray的类型

type(a.dtype)

# 结果 numpy.dtypes.Int32DType

dtype是numpy.dtype类型,先看看对于数组来说都有哪些类型

名称 描述 简写
np.bool 用一个字节存储的布尔类型 (True或False) ‘b’
np.int8 一个字节大小,-128 至127 ‘i’
np.int16 整数,-32768至32767 ‘i2’
np.int32 整数,-2 31次方至 2 31次方 -1 ‘i4’
np.int64 整数,-2 63次方至 2 63次方 -1 ‘i8’
np.uint8 无符号整数,0至255 ‘u’
np.uint16 无符号整数,0至65535 ‘u2’
np.uint32 无符号整数,0至2 ** 32 -1 ‘u4’
np.uint64 无符号整数,0至2 ** 64 -1 ‘u8’
np.float16 半精度浮点数: 16位,正负号1位,指数5位,精度10位 ‘f2’
np.float32 单精度浮点数: 32位,正负号1位,指数8位,精度23位 ‘f4’
np.float64 双精度浮点数: 64位,正负号1位,指数11位,精度52位 ‘f8’
np.complex64 复数,分别用两个32位浮点数表示实部和虚部 ‘c8’
np.complex128 复数,分别用两个64位浮点数表示实部和虚部 ‘c16’
np.object_ python对象 ‘O’
np.string_ 字符串 ‘S’
np.unicode_ unicode类型 ‘U’

Numpy_第4张图片
我的电脑 整数默认是int32,浮点型默认是float64

四、创建数组的时候指定类型

a = np.array([[1,2,3],[4,5,6]], dtype=np.float64)
a.dtype

arr = np.array(["qingfeng", "yun", "yijing"], dtype=np.string_)# 不常用
arr

Numpy_第5张图片
若不指定类型,按默认

Numpy是一个高效的运算工具,在处理字符串的时候,Numpy并不是十分的具有优势

五、基本操作

  • ndarray.方法()
  • numpy.函数名()
    • numpy.array()

生成数组的方法

生成0和1的数组

  • empty(shape[, dtype, order]) empty_like(a[, dtype, order, subok])
    eye(N[, M, k, dtype, order])
  • identity(n[, dtype])
  • ones(shape[, dtype, order])
  • ones_like(a[, dtype, order, subok])
  • zeros(shape[, dtype, order]) zeros_like(a[, dtype, order, subok])
    full(shape, fill_value[, dtype, order])
  • full_like(a, fill_value[, dtype, order, subok])

记两个就好了

import numpy as np
np.zeros(shape=(3,4),dtype="float32")
np.ones(shape=[2,3],dtype=np.int32)

Numpy_第6张图片
我们想要指定形状shape既可以是元组()又可以是列表[ ]

从现有数组生成

  • array(object[, dtype, copy, order, subok, ndmin])深拷贝
  • asarray(a[,dtype, order])浅拷贝
  • asanyarray(a[, dtype, order]) ascontiguousarray(a[, dtype])
  • asmatrix(data[, dtype])
  • copy(a[, order])深拷贝
a = np.array([[1,2,3],[4,5,6]])
#  从现有的数据当中创建
a1 = np.array(a)
#  相当于索引的形式,并没有真正的创建一个新的
a2 = np.asarray(a)

a3 = np.copy(a)

Numpy_第7张图片

看起来是没有什么变化,但实际上我们可以去修改原始现有的数组。

a[1,2] # 找到第二行第三列的数据
a[1,2] = 66666666 # 修改第二行第三列的数据

Numpy_第8张图片
修改数据后,得出结论:(他们的不同点
np.array() 、 np.copy() 是深拷贝
np.asarray() 是浅拷贝

生成固定范围的数组

  • np.linspace(start,stop,num,endpoint,retstep,dtype)
    生成等间隔的序列(左闭右闭区间)
start 序列的起始值
stop 序列的终止值
如果endpoint为true,该值包含于序列中
num 要生成的等间隔样例数量,默认为50
endpoint 序列中是否包含stop值,默认为ture
retstep 如果为true,返回样例,
以及连续数字之间的步长
dtype输出ndarray的数据类型
np.linspace(-1,1,1000)
# 生成-1到1之间 等距离 的生成一千个元素
#  [-1,...,1] 左闭右闭区间
  • np.arange( a, b, c)
    [a,b) 左闭右开区间 ,c是步长
    • 跟 range() 相似
      range(a,b,c)    [a,b) 左闭右开区间 ,c是步长
      Numpy_第9张图片
  • np.logspace(start, stop, num=50,endpoint=True, base=10.0, dtype=None)
    • 对数等比数列
    • start=开始值,stop=结束值,num=元素个数,base=指定对数的底, endpoint=是否包含结束值
    • https://numpy.org/devdocs/reference/generated/numpy.logspace.html#numpy.logspace
      Numpy_第10张图片

生成随机数组

  • np.random模块
    • 均匀分布
      • np.random.rand(d0, d1, …, dn)
        返回 [ 0.0, 1.0)内的一组均匀分布的数。
      • np.random.uniform(low=0.0, high=1.0, size=None)
        功能:从一个均匀分布 [ low,high) 中随机采样,注意定义域是左闭右开,即包含low,不包含high。
        参数介绍:
        low: 采样下界,float类型,默认值为0;
        high: 采样上界,float类型,默认值为1;
        size: 输出样本数目,为int或元组(tuple)类型,例如,size=(m,n,k), 则输出mnk个样本,缺省时输出1个值。
        返回值: ndarray类型,其形状和参数size中描述一致。
      • np.random.randint(low, high=None, size=None, dtype=‘I’)
        从一个均匀分布中随机采样,生成一个整数或N维整数数组,取数范围: 若high不为None时, 取 [low,high)之间随机整数,否则取值[0,low)之间随机整数。

均匀分布(Uniform Distribution) 是概率统计中的重要分布之一。顾名思义,均匀,表示可能性相等的含义。均匀分布在自然情况下极为罕见,而人工栽培的有一定株行距的植物群落即是均匀分布。

data = np.random.uniform(low=-1, high=1.0, size=100000)
data

import matplotlib.pyplot as plt
# 1. 创建画布
plt.figure(figsize=(20,8),dpi=80)

# 2. 绘制直方图
plt.hist(data,1000)# 1000组
# 3. 显示图像
plt.show()

Numpy_第11张图片

第一行代码 np.random.uniform(low, high=, size=100000) 的size参数设的更大这个图会更加平。

  • 正态分布
    • np.random.randn(d0, d1, …, dn)
      功能: 从标准正态分布中返回一个或多个样本值
    • np.random.normal(loc=0.0, scale=1.0, size=None)
      loc: float
      此概率分布的均值(对应着整个分布的中心centre)
      scale: float
      此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
      size: int or tuple of ints
      输出的shape,默认为None,只输出一个值
  • np.random.standard_normal(size=None)
    返回指定形状的标准正态分布的数组。
import numpy as np
# 生成正态分布的一组数,loc:均值;scale:标准差
data2 = np.random.normal(loc=1.75, scale=0.1, size=1000000)
import matplotlib.pyplot as plt
# 1. 创建画布
plt.figure(figsize=(20,8),dpi=80)

# 2. 绘制直方图
plt.hist(data2,1000)# 1000组
# 3. 显示图像
plt.show()

Numpy_第12张图片

补充:正态分布 (理解)
正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的标准差,所以正态分布记作N(μ,σ)。σ平方是方差

Numpy_第13张图片
生活、生产与科学实验中很多随机变量的概率分布都可以近似地用正态分布来描述。

正态分布特点
μ决定了其位置,其标准差σ。决定了分布的幅度(或者 波动程度、集中程度、稳定性)。当 μ=0, σ=1时的正态分布是标准正态分布。
Numpy_第14张图片

方差
在概率论和统计学中衡量一组数据离散程度的度量
在这里插入图片描述
其中M为平均值,n为数据总个数,S为标准差,S^2可以理解一个整体为方差。
Numpy_第15张图片
方差、标准差越小,证明这个稳定性越好;而方差、标准差越大,波动程度越大或者稳定性越差

案例:随机生成8只股票2周的交易日涨幅数据

  • 8只股票,两周(10天) 的涨跌幅数据,如何获取?
    • 两周的交易日数量为: 2X5=10
    • 随机生成涨跌幅在某个正态分布内,比如均值0,方差1
import numpy as np
stock_change = np.random.normal(loc=0, scale=1, size=(8,10))# 8只股票,两周10天交易日
stock_change

返回结果:

array([[-0.36667531, -1.13903035,  0.4784379 ,  1.53073633,  0.91670121,
        -0.10350913,  1.99079752, -0.14177123, -0.96660077,  0.81775223],
       [-1.71483356, -0.75371119, -0.46216504, -0.0300214 , -0.08352358,
         0.07012395, -0.32508192, -0.95563982, -0.67952454, -2.34651391],
       [ 0.0483106 ,  0.49960887, -0.51479725, -0.11741516, -0.56064551,
        -1.10703553, -0.36689492, -0.45247859,  0.36211534, -0.01616913],
       [-0.86345178,  0.50887156,  1.54648113, -0.78605471,  0.23232971,
         0.0196267 , -0.63385226, -0.61201315, -1.31778512, -0.74808621],
       [-0.93646108,  1.02844702,  0.70762638, -1.10396096, -0.14237001,
         1.55326396, -0.07842413, -1.49910403, -1.01194549,  1.31681139],
       [ 1.89151096,  0.12276531,  0.98818101,  2.27713536, -0.41012269,
         2.0600995 ,  0.76081549,  1.32616142,  1.01333746, -1.0480584 ],
       [ 0.37474226, -1.12586255, -0.23056892,  0.41170971,  0.06305395,
        -1.11060202, -0.41773649,  1.19974127,  0.67841274, -0.36691069],
       [-2.1010863 ,  1.05177172, -1.72547563, -0.27451417,  1.28503123,
         0.24951152, -1.14881235,  1.86966196, -0.16858585, -0.60438892]])

数组的索引、切片

  • 获取第一只股票的前3个交易日的涨跌幅数据

    • 二维数组

      stock_change[0,:3]
      或者stock_change[0,0:3]
      

      返回结果:

      array([-0.36667531, -1.13903035,  0.4784379 ])
      
    • 三维数组
      Numpy_第16张图片

形状修改

需求:让刚才的股票 行、列 数据反过来,进行一个反转

  • ndarray.reshape(shape)
    ndarray.reshape((a,b))
    只是对数据进行重新分割,排列顺序没有改变,只是修改了形状
    返回新的ndarray,原始数据没有改变

    • ndarray.reshape( (-1,b) )
      自动计算的功能,如果我们只想指定生成4列的数组,剩下的我就不想自己计算了,就把另一个位置写成-1
      Numpy_第17张图片
      Numpy_第18张图片
  • ndarray.resize(shape)
    只是对数据进行重新分割,排列顺序没有改变,只是修改了形状(与reshape一样,唯一的不同是resize会修改原数据)
    没有返回值,对原始的ndarray进行了修改
    Numpy_第19张图片

  • ndarray.T
    数组的转置,行变成列,列变成行
    原始数据没有改变
    Numpy_第20张图片

类型修改

ndarray.astype(type)

import numpy as np
stock_change = np.random.normal(loc=0, scale=1, size=(8,10))

stock_change

stock_change.dtype

stock_change.astype("int64")

Numpy_第21张图片

ndarray序列化到本地

ndarray.tostring([order]) 或者 ndarray.tobytes([order]) Construct Python bytes containing the raw data bytes in the array.

就需要先将他写成byte类型,ndarray.tostring() 现在已经被弃用了,现在用ndarray.tobytes()
Numpy_第22张图片
如果遇到:

IOPub data rate exceeded.
	The notebook server will temporarily stop sending output
	to the client in order to avoid crashing it.
	To change this limit, set the config variable
	`--NotebookApp.iopub_data_rate_limit'.

这个问题是在jupyer当中对输出的字节数有限制,需要去修改配置文件

创建配置文件

jupyter notebook --generate-config
vi ~/.jupyter/jupyter_notebook_config.py

取消注释,多增加

## (bytes/sec) Maximum rate at which messages can be sent on iopub before they
# are limited.
c.NotebookApp.iopub_data_rate_limit = 10000000

但是不建议这样去修改,jupyter输出太大会崩溃

数组的去重

ndarray.unique

temp = np.array([[1, 2, 3, 4,5],[3, 4, 5, 6,5]])
np.unique(temp)

结果 :

array([1, 2, 3, 4, 5, 6])

如果想要用set()
可以先把这个数组变成一维数组 ndarray.flatten()

temp.flatten()
set(temp.flatten())

Numpy_第23张图片

六、ndarray运算

6.1 逻辑运算

运算符

import numpy as np
stock_change = np.random.normal(loc=0, scale=1, size=(8,10))
stock_change

# 逻辑判断, 如果涨跌幅大于0.5就标记为True 否则为False
stock_change > 0.5

stock_change[stock_change > 0.5] = 1.1 # 布尔索引
stock_change

Numpy_第24张图片
布尔索引
Numpy_第25张图片

Numpy_第26张图片

通用判断函数

  • np.all(一组布尔值)
    只要有一个false就返回false,只有全部是true才返回 true
# 判断stock_change[0:2, 0:5]是否全是上涨的
np.all(stock_change[0:2, 0:5] > 0)

Numpy_第27张图片

  • np.any(一组布尔值)
    只要有一个true就返回true,只有全部是false才返回 false
# 判断前5只股票这段期间是否有上涨的
np.any(stock_change[:5, :] > 0)

三元运算符

  • np.where(布尔值,True的位置的值,False的位置的值)
import numpy as np
stock_change = np.random.normal(loc=0, scale=1, size=(8,10))# 8只股票,两周10天交易日
# 判断前四个股票前四天的涨跌幅 大于0的置为1,否则为0
temp = stock_change[:4, :4]

temp
#  返回结果:array([[-0.39816959, -0.60027098, -0.8698318 ,  0.05142684],
#       [-0.88684009,  1.03198298,  0.03543764, -1.2045695 ],
#       [ 0.56317106, -0.28580609, -0.13242459,  0.79477531],
#       [-1.36364381, -1.42141649, -3.78067491, -0.32461608]])
       
np.where(temp > 0, 1, 0)
#返回结果:array([[0, 0, 0, 1],
#       [0, 1, 1, 0],
#       [1, 0, 0, 1],
#       [0, 0, 0, 0]])

temp > 0
#返回结果:array([[False, False, False,  True],
#       [False,  True,  True, False],
#       [ True, False, False,  True],
#       [False, False, False, False]])

# 一个效果
np.where([[False, False, False,  True],
       [False,  True,  True, False],
       [ True, False, False,  True],
       [False, False, False, False]], 1, 0)
#返回结果:array([[0, 0, 0, 1],
#       [0, 1, 1, 0],
#       [1, 0, 0, 1],
#       [0, 0, 0, 0]])
  • 复合逻辑需要结合np.logical_andnp.logical_or使用
# 大于0.5且小于1
np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)
# 大于0.5或小于-0.5
np.where(np.logical_or(temp > 0.5, temp < -0.5), 11, 3)

6.2 统计运算

统计指标函数

  • min(最小值), max(最大值), mean(平均值), median(中位数),var(方差), std(标准差)

股票涨跌幅统计运算

进行统计的时候,axis 轴的取值并不一定,Numpy中不同的API轴的值都不一样,在这里,axis 0代表列,axis 1代表行 去进行统计

stock_change = np.random.normal(loc=0, scale=1, size=(8,10))# 8只股票,两周10天交易日
temp = stock_change[:4, :4]

temp.max(axis=0)
np.max(temp, axis=1)

Numpy_第28张图片

技巧:temp 的形状是(4行,4列),(4,4) 元组索引是 0 、1 ,其中索引 -1 和 1是一样的。
所以 np.max(temp, axis=1)和np.max(temp, axis=-1) 是一个效果

返回最大值、最小值的位置

  • np.argmax(tem,axis=)

  • np.argmin(tem,axis=)

axis 0代表列,axis 1代表行

如果需要统计出哪一只股票在某个交易日的涨幅最大或者最小?

np.argmax(temp, axis=1)

Numpy_第29张图片

6.3 数组间运算

数组与数的运算

import numpy as np
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])

arr / 10

返回结果:

array([[0.1, 0.2, 0.3, 0.2, 0.1, 0.4],
       [0.5, 0.6, 0.1, 0.2, 0.3, 0.1]])

数组与数组的运算

广播机制

执行 broadcast 的前提在于,两个 nadarray 执行的是 element-wise 的运算,Broadcast 机制的功能是为了方便不同形状的 ndarray(numpy 库的核心数据结构)进行数学运算。

当操作两个数组时,numpy 会逐个比较它们的 shape(构成的元组 tuple),只有在下述情况下,两个数组才能够进行数组与数组的运算。

  • 维度相等
  • shape(其中相对应的一个地方为 1)

    简单点就是:两个数组的同维度元素数量,要么相等要么其中一个为1

例如:这些都是可以运算的。 Result 是运算结果的形状,最终的每个维度都是取最大的。

Image (3d array): 256 x 256 x 3			第一个数组
Scale (1d array):             3			第二个数组
Result(3d array): 256 x 256 x 3

这里第一个数组是三维数组,这个三维数组的形状是(256 , 256 , 3 )。第二个是一维数组,有三个元素。形状从右往左依次排开,可以这么理解,因为最后维度是3,想象成三列,Scale 里面的每一个元素与Image的每一列进行运算。

Numpy_第30张图片
形状从右往左依次排开,每个对应的地方要么相等要么是1,不满足就不能运算。

Result (4d array) : 9   8(1和8比较)   7(7和1比较)  5(1和5比较)

Numpy_第31张图片

如果刚刚好全都是4,那么就按照顺序一一对应去计算就行了,如果是1的话,它就可以将这一份分别去跟别人的多份去进行计算,如果是2或者其他的话,那么它就没办法这样计算。

Numpy_第32张图片


下面是不能运算的
在这里插入图片描述
维度要么相等要么为1
Numpy_第33张图片


思考:下面两个ndarray是否能够进行运算?

arr1 = np.array([[1,2,3,2,1,4],[5,6,1,2,3,1]])
arr2 = np.array([[1],[3]])

维度要么相等要么为1,所以 arr1 可以和 arr2 进行运算
Numpy_第34张图片

我是这么理解的,维度如果是1的话,可以把他当做一个数,数组与数的运算,单个数分别与数组中的数进行运算

矩阵运算

英文 matrix,和 array 的区别是矩阵必须是 2 维的 (二维数组),但是 array 可以是多维的。

矩阵存储在计算机当中是二维数组的,但是二维数组不一定是矩阵,矩阵和二维数组的区别?

两种方法存储矩阵
1)ndarray 二维数组

  • 矩阵乘法
    • np.matmul
    • 扩展: ndarray @ ndarray       也能实现相同的效果,了解即可

2)matrix 数据结构

  • np.mat()  将数组转换成矩阵类型, 返回值是matrix
  • 矩阵乘法
    • np.dot
    • matrix * matrix

下面是学生成绩数据 [左边平时成绩,右边期末成绩]
(8,2) 8行2列

import numpy as np
# ndarray  存储矩阵  [左边平时成绩,右边期末成绩]
data = np.array([[80,86],
                [80,82],
                [85,78],
                [90,90],
                [86,82],
                [82,90],
                [78,80],
                [92,94]])

# matrix  存储矩阵
data_mat = np.mat([[80,86],
                [80,82],
                [85,78],
                [90,90],
                [86,82],
                [82,90],
                [78,80],
                [92,94]])

Numpy_第35张图片

矩阵乘法运算

矩阵乘法的两个关键:

  • 形状改变
  • 运算规则

形状改变:(M 行,N 列)x (N 行,L 列) = (M 行,L 列)

运算规则:
Numpy_第36张图片
要想最终能进行矩阵运算,所以第二个是 (2, ?) 2行随便几列都可以,因为我们只想要一个成绩, 所以是一列。

(8,2)x (2,1) = (8,1)

import numpy as np
# ndarray  存储矩阵  [左边平时成绩,右边期末成绩]
data = np.array([[80,86],
                [80,82],
                [85,78],
                [90,90],
                [86,82],
                [82,90],
                [78,80],
                [92,94]])

# matrix  存储矩阵
data_mat = np.mat([[80,86],
                [80,82],
                [85,78],
                [90,90],
                [86,82],
                [82,90],
                [78,80],
                [92,94]])
weights = np.array([[0.3],[0.7]])  # 平时成绩占30%,期末成绩占70%
weights_mat = np.mat([[0.3],[0.7]])

np.matmul(data,weights) # 总成绩=平时成绩*30%+期末成绩*70%
np.dot(data_mat,weights_mat)
data_mat * weights_mat # 也是一样的结果
data @ weights  # 也是一样的结果

Numpy_第37张图片

ndarray @ ndarray 和 matrix * matrix 也可以达到相同的效果

Numpy_第38张图片
矩阵和二维数组的区别:矩阵是用二维数组存储的,二维数组不一定是矩阵。

因为data 和 weights 都是ndarray 是普通的数组,data * weights 是数组间的运算,要看他是否满足广播机制,data 形状是(8,2)、weights形状是(2,1),他们维度不满足广播机制,不能进行运算,所以会报错。
Numpy_第39张图片
在这里插入图片描述

Numpy_第40张图片

6.4 合并、分割

合并

  • numpy.hstack 水平拼接

    import numpy as np
    a = np.array( (1,2,3) )
    b = np.array( (2,3,4,5) )
    np.hstack((a,b))
    # 返回结果:array([1, 2, 3, 2, 3, 4, 5])
    a = np.array( [ [1],[2],[3] ] )
    b = np.array( [[2],[3],[4]] )
    np.hstack((a,b))
    # 返回结果:array([[1, 2],
    #       [2, 3],
    #       [3, 4]])
    

    水平拼接可以这么理解:
    1.

    [1,2,3] [2,3,4,5]


    [[1],  [[2],
    [2],  [3],
    [3]]  [4]]

  • numpy.vstack 竖拼接

    a = np.array( [1,2,3] )
    b = np.array( [2,3,4] )
    np.vstack((a,b))
    # 返回结果:array([[1, 2, 3],
    #			   [2, 3, 4]])
    a = np.array( [ [1],[2],[3] ] )
    b = np.array( [[2],[3],[4],[5]] )
    np.vstack((a,b))
    # 返回结果:array([[1],
    #   			 [2],
    #   			 [3],
    #   			 [2],
    #   			 [3],
    #   			 [4],
    #   			 [5]])
    
  • numpy.concatenate((a1,a2),axis=0) 水平|竖拼接

    • 通过指定维度或者说轴(axis)的方式来指定到底是 水平 还是 竖直 拼接。
    • 1 水平
    • 0 竖直
    a = np.array( [[1,2],[3,4]] )
    b = np.array( [[5,6] ])
    np.concatenate((a,b),axis=0)
    # array([[1, 2],
    #       [3, 4],
    #       [5, 6]]) 
    
    b.T # 数组转置,行变成列,列变成行  array([[5], [6]])
    np.concatenate((a,b.T),axis=1)
    # array([[1, 2, 5],
    #       [3, 4, 6]])
    

分割

  • numpy.split

用到查文档

x = np.arange(9.0)
x # array([0., 1., 2., 3., 4., 5., 6., 7., 8.])
np.split(x,3)
x = np.arange(8.0)
x # array([0., 1., 2., 3., 4., 5., 6., 7.])
np.split(x,[3,5,6,10])

Numpy_第41张图片

6.5 IO 操作与数据处理

Numpy读取数据

  • np.genfromtxt(路径, delimiter=分隔符)

新建一个test.csv文件,内容:

id, value1, value2,value3
1,123,1.4,23
2,110,,18
3,,2.1,19
data = np.genfromtxt("test.csv", delimiter=",") # 会有问题,读不出字符串

Numpy_第42张图片
我们发现本来第一行字段应该读成字符串的,但是却读成了nan(Not a Number),我们把缺失值记作nan。

什么是缺失值?
什么时候numpy中会出现nan: 当我们读取本地的文件为float的时候,如果有缺失(或者为None),就会出现nan。nan是float64类型, nan == nan 结果是False

Numpy_第43张图片

如何处理缺失值

两种思路:

  • 直接删除含有缺失值的样本(那一行或者那一列),在pandas中介绍

  • 替换/插补 (补入平均值或中位数)

    处理逻辑:

    def fill_nan_by_column_mean(t):
        for i in range(t.shape[1]):
            # 计算nan的个数
            nan_num = np.count_nonzero(t[:,i][ t[:,i] != t[:,i] ])
            if nan_num > 0:
                now_col = t[:,i]
                # 求和
                now_col_not_nan = now_col[np.isnan(now_col) == False].sum()# 和/个数
                now_col_mean = now_col_not_nan / (t.shape[0] - nan_num)
                # 赋值给now_col
                now_col[np.isnan(now_col)] = now_col_mean
                # 赋值给t,即更新t的当前列
                t[:, i] = now_col
        return t
    
    
    fill_nan_by_column_mean(data)
    

    Numpy_第44张图片

    看了上面的处理过程,非常麻烦,别担心,之后我们会介绍强大的Pandas工具进行处理! 其实Pandas里面也是集成了Numpy。

你可能感兴趣的:(#,Python数据挖掘基础,numpy,python,数据挖掘,开发语言)