系列文章目录
第一章 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 对象来处理多维数组,该对象是一个快速而灵活的大数据容器。
ndarray
- n = 任意个
- d = dimension 维度
- array = 数组
NumPy 提供了一个 N 维数组类型 ndarray,它描述了相同类型的"items"的集合
优势
- 存储风格
- ndarray -
相同类型数据
- 通用性不强 - list - 不同类型 - 通用性很强
- ndarray -
- 并行化运算
- ndarray 支持向量化运算
- 底层语言
- 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)) # <class 'numpy.ndarray'>
print(score.shape) # (8, 5)
print(score.dtype) # int32
二、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) 三维数组
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’ |
我的电脑 整数默认是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是一个高效的运算工具,在处理字符串的时候,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)
我们想要指定形状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)
看起来是没有什么变化,但实际上我们可以去修改原始现有的数组。
a[1,2] # 找到第二行第三列的数据
a[1,2] = 66666666 # 修改第二行第三列的数据
修改数据后,得出结论:(他们的不同点)
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是步长
- 跟 range() 相似
- 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
生成随机数组
- 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)之间随机整数。
- np.random.rand(d0, d1, …, dn)
- 均匀分布
均匀分布(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()
第一行代码 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.randn(d0, d1, …, dn)
- 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()
补充:正态分布 (理解)
正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的标准差,所以正态分布记作N(μ,σ)。σ平方是方差
生活、生产与科学实验中很多随机变量的概率分布都可以近似地用正态分布来描述。
正态分布特点
μ决定了其位置,其标准差σ。决定了分布的幅度(或者 波动程度、集中程度、稳定性)。当 μ=0, σ=1时的正态分布是标准正态分布。
方差
在概率论和统计学中衡量一组数据离散程度的度量
其中M为平均值,n为数据总个数,S为标准差,S^2可以理解一个整体为方差。
方差、标准差越小,证明这个稳定性越好;而方差、标准差越大,波动程度越大或者稳定性越差
案例:随机生成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 ])
-
三维数组
-
形状修改
需求:让刚才的股票 行、列 数据反过来,进行一个反转
-
ndarray.reshape(shape)
ndarray.reshape((a,b))
只是对数据进行重新分割,排列顺序没有改变,只是修改了形状
返回新的ndarray,原始数据没有改变ndarray.reshape( (-1,b) )
自动计算的功能,如果我们只想指定生成4列的数组,剩下的我就不想自己计算了,就把另一个位置写成-1
-
ndarray.resize(shape)
只是对数据进行重新分割,排列顺序没有改变,只是修改了形状(与reshape一样,唯一的不同是resize会修改原数据)
没有返回值,对原始的ndarray进行了修改
-
ndarray.T
数组的转置,行变成列,列变成行
原始数据没有改变
类型修改
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")
ndarray序列化到本地
ndarray.tostring([order]) 或者 ndarray.tobytes([order]) Construct Python bytes containing the raw data bytes in the array.
就需要先将他写成byte类型,ndarray.tostring() 现在已经被弃用了,现在用ndarray.tobytes()
如果遇到:
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())
六、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
布尔索引
通用判断函数
np.all(一组布尔值)
只要有一个false就返回false,只有全部是true才返回 true
# 判断stock_change[0:2, 0:5]是否全是上涨的
np.all(stock_change[0:2, 0:5] > 0)
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_and
和np.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)
技巧: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)
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的每一列进行运算。
形状从右往左依次排开,每个对应的地方要么相等要么是1,不满足就不能运算。
Result (4d array) : 9 8(1和8比较) 7(7和1比较) 5(1和5比较)
如果刚刚好全都是4,那么就按照顺序一一对应去计算就行了,如果是1的话,它就可以将这一份分别去跟别人的多份去进行计算,如果是2或者其他的话,那么它就没办法这样计算。
下面是不能运算的
维度要么相等要么为1
思考:下面两个ndarray是否能够进行运算?
arr1 = np.array([[1,2,3,2,1,4],[5,6,1,2,3,1]])
arr2 = np.array([[1],[3]])
维度要么相等要么为1,所以 arr1 可以和 arr2 进行运算
我是这么理解的,维度如果是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]])
矩阵乘法运算
矩阵乘法的两个关键:
- 形状改变
- 运算规则
形状改变:(M 行,N 列)x (N 行,L 列) = (M 行,L 列)
运算规则:
要想最终能进行矩阵运算,所以第二个是 (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 # 也是一样的结果
ndarray @ ndarray 和 matrix * matrix 也可以达到相同的效果
矩阵和二维数组的区别:矩阵是用二维数组存储的,二维数组不一定是矩阵。
因为data 和 weights 都是ndarray 是普通的数组,data * weights 是数组间的运算,要看他是否满足广播机制,data 形状是(8,2)、weights形状是(2,1),他们维度不满足广播机制,不能进行运算,所以会报错。
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])
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=",") # 会有问题,读不出字符串
我们发现本来第一行字段应该读成字符串的,但是却读成了nan(Not a Number),我们把缺失值记作nan。
什么是缺失值?
什么时候numpy中会出现nan: 当我们读取本地的文件为float的时候,如果有缺失(或者为None),就会出现nan。nan是float64类型, nan == nan 结果是False
。
如何处理缺失值
两种思路:
-
直接删除含有缺失值的样本(那一行或者那一列),
在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)
看了上面的处理过程,非常麻烦,别担心,之后我们会介绍强大的Pandas工具进行处理! 其实Pandas里面也是集成了Numpy。