轴的概念:
在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于二维数组(shape(2, 2)), 有0轴和1轴,对于三维数组(shape(2, 2, 3)),有0,1,2轴(分别对应数组的(“块”,“行”, “列”))
二维数组的轴
三维数组的轴:
import numpy as np
"""
numpy读取数据:
np.loadtxt(frame, dtype=np.float, delimiter=None, skiprows=0, usecols=None,unpack=False)
参数:
frame: 文件、字符串或产生器,可以是.gz或bz2压缩文件
dtype:数据类型,可选,CSV的字符串以什么数据类型读入数组中,默认np.float
delimiter: 分隔字符串,默认是任何空格
skiprows: 跳过前x行,一般跳过第一行表头
usecols: 读取指定的列,索引,元组类型
unpack:如果True,则转置,读入属性将分别写入不同数组变量,False读入数据值写入一个数组变量,默认为False
说明:
np.loadtxt(filepath_csv, delimiter=",", dtype=int, unpack=True)
注意其中添加delimiter和dtype以及unpack的效果
delimiter:指定边界符号是什么,不指定会导致每行数据为一个整体的字符串而报错
dtype:默认情况下对于较大的数据会采用科学计数法的方式
那么unpack的效果呢:
unpack:默认是False(0),默认情况下,有多少条数据,就有多少行,
为True(1)的情况下,每一列的数组会组成一行,原始数据有多少列,加载出来的数据就有多少行,相当于转置的效果(行变为列,列变成行)
"""
转置就是将行变为列,列变为行的效果
import numpy as np
# 将t1转置的3种方法
t1 = np.arange(10).reshape((2, 5))
# 1.转置,行变为列,列变成行,数学中的T表示为转置
t2 = t1.T
# 2.转置,使用transpose()函数
t3 = t1.transpose()
# 3.交换轴进行转置
t4 = t1.swapaxes(1, 0)
print(t1)
print("*" * 100)
print(t4)
在numpy中索引与python的的索引是一样的,都是从0开始
通用方法,在中括号中",“前写行”,"后写列
import numpy as np
# 创建一个二维数组
t1 = np.arange(1, 10001).reshape(2500, 4)
# 取行
# 取第二行
# 取第3行, 下标为2
# t2 = t1[2]
# print(t2)
# 取多行,取第1行到第三行
# t2 = t1[0:3]
# 取连续的多行,从第三行一直到结尾
# t2 = t1[2:]
# 取不连续的多行, 取第一行,第3行和最后一行
# t2 = t1[[0, 2, -1]]
# 通用方法,在","前写行","后写列
# print(t1[0, :]) # 第一行
# print(t1[2:, :]) # 第3行到最后一行
# print(t1[[0, 2, -1], :]) # 取第一行,第3行和最后一行
# 取列
# 取第一列
# t2 = t1[:, 0]
# 取连续的多列, 从第2列到最后一列
# t2 = t1[:, 1:]
# 取不连续的多列
# t2 = t1[:, [0, 1, -1]]
# 取行和列,取第3行,第四列之中的交点的值
# t2 = t1[2, 3]
# 取多行和多列,第三行到第五行,第2列到第四列的值
# t2 = t1[2:5, 1:4]
# 取多个不相邻的点
# 选出来的结果是(0,0), (1, -1), (-1, 2)
t2 = t1[[0, 1, -1], [0, -1, 2]]
print(t1)
print("*" * 100)
print(t2)
更多索引的方式包括布尔索引、np.where三元运算符和裁剪np.clip
import numpy as np
# numpy 中数值的修改
t1 = np.arange(1, 25).reshape(4, 6)
# 将3行4列的值修改为0
# t1[2, 3] = 0
# 将t1中大于5的值修改为0
# t1[t1 > 5] = 0
# print(t1)
# numpy中的布尔索引
# print(t1<10)
# 问题: 如果我们想把t1中小于10的数字替换为0,把大于10的替换为10,应该怎么做
# numpy中的三元运算符where
# numpy中的三元运算符类似于python中的三元运算符
# t1 = np.where(t1 < 10, 0, 10) # 第一个为条件,第二个为满足条件所替换数字,第三个为不满足条件所替换的数字
# a = 3 if 3 > 2 else 4 # python中的3元运算符
# 问题:如果我们向把t中小于10的数字替换为10,把大于20的替换为20,应该怎么做
# numpy中的clip(剪裁)
# t1 = t1.clip(10, 20)
# t1.clip(10, 20)在10到20之间的数字不替换,第一个参数(10)表示比它(10)小的值替换为第一个参数(10),第二个参数(20)表示比它(20)大的数字替换为第二个参数(20)
nan: 全称not a number,表示不是一个数字,它为float类型, 有关nan的用法后面会进行详细讲解
import numpy as np
# 将第2行第三列的值变为nan
t1 = np.arange(12).reshape((3, 4))
t1 = t1.astype(float) # 转变数组类型
t1[1, 2] = np.nan
print(t1)
numpy中拼接的方法有vstack(竖直拼接)和hstack(水平拼接)等多种方法,当然还会有分割的方法,这里就不过多赘述了,感兴趣的可以去numpy官方文档numpy中文官方文档
import numpy as np
t1 = np.arange(12).reshape(2, 6)
t2 = np.arange(12, 24).reshape(2, 6)
print(t1)
t3 = np.vstack((t1, t2)) # 竖直拼接,谁的参数在左边,谁的值就在上方
# print(t3)
"""
结果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
"""
t4 = np.hstack((t1, t2)) # 水平拼接,谁的参数在左边,谁的值就在左边
# print(t4)
"""
结果:
[[ 0 1 2 3 4 5 12 13 14 15 16 17]
[ 6 7 8 9 10 11 18 19 20 21 22 23]]
"""
"""
数组的行列交换:
数组水平或者竖直拼接很简单,但是拼接之前应该注意什么呢?
数值拼接的时候:每一列代表的意义应该相同!!!否则牛头不对马嘴
如果每一列的意义不同,这个时候应该交换某一组的数的列,让其和另外一类相同
"""
# 数组的行列交换
t1[[0, 1], :] = t2[[1, 0], :] # 行交换, 将t1中的第二行和第三行交换为t2的第三行和第二行
print("*" * 100)
print(t1)
数据拼接的小案例
import numpy as np
# 数组拼接小案例
np.random.seed(100) # 设定一个随机数种子
t1 = np.random.randint(1000, 10000, (250, 4)).astype(int) # 生成一个1000到10000之间的250行4列的随机数组
t2 = np.random.randint(1000, 10000, (250, 4)).astype(int)
# 构造全为1的数组
ones = np.ones((t1.shape[0], 1)).astype(int)
# 构造全为0的数组
zeros = np.zeros((t1.shape[0], 1)).astype(int)
# 分别添加一列全为1, 0的数组
t1 = np.hstack((t1, ones)) # 水平拼接
t2 = np.hstack((t2, zeros))
# 竖直拼接俩组数据
data = np.vstack((t1, t2))
print(data)
numpy.random生成随机数
参数 解释
.rand(d0,d1,...dn) 创建d0-dn维度的均匀分布的随机数数组,浮点数,范围从0-1
.randn(d0,d1,...dn) 创建d0-dn维度的标准正态分布随机数,浮点数,平均数0,标准差1
.randint(low, high,(shape)) 从给定上下限范围选取随机整数,范围是low,high,形状是shape
.uniform(loc,scale, (size)) 从指定正太分布中随机抽取样本,分布中心是loc(概率分布的均值),标准差是scale,形状是size
.seed(s) 随机数种子,s是给定的种子值。因为计算机生成的是伪随机数,所以通过设定相同的随机种子,可以每次生成相同的随机数
numpy中的nan和inf
nan(NAN, Nan): not a number表示不是一个数字
什么时候numpy会出现nan:
当我们读取本地文件为float的时候,如果有缺失,就会出现nan
当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)
inf(-inf, inf): infinity, inf表示正无穷,-inf表示负无穷
什么时候会出现inf包括(-inf, inf)
比如一个数字除以0,(python中会直接会报错,numpy中是一个inf或者-inf)
那么如何指定一个nan或者inf呢?
注意它们的type类型 ==> a = np.inf type(a)
注意它们的type类型 ==> a = np.nan type(a)
它们都是float类型.
numpy中的nan注意点
1.两个nan是不相等的 np.nan == np.nan ==> False
2.np.nan !== np.nan np.nan !== np.nan ==> True
3.利用以上特性,判断数组中的nan的个数
t = np.array([1., 2., nan])
np.count_nonzero(t!=t) ==> 1
说明: count_nonzero()函数是判断数组中不为0的数的个数,当传入参数t!=t时,则返回bool类型,然后返回数组中为true的个数
4.由于2,那么如何判断一个数字是否是nan呢?通过np.isnan(a)来判断,返回bool类型,比如希望把nan替换为0,所以我们也可以使用count_nonzero(np.isnan(a))来获取nan的个数
t = np.array([1., 2., nan])
t[np.isnan(t)] = 0
t ==> array([1., 2., 0])
5.nan和任何值计算都为nan
numpy中的nan的注意点:
那么问题来了,在一组数据中单纯的把nan替换你为0,合适么?会受到什么样的影响?
答:比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以一般的方式是把缺失的数值替换为均值(中值)或者直接删除有缺失值的一行
numpy中常用的统计函数:
求和:t.sum(axis=None)
均值: t.mean(a, axis=None) 受离群点的影响较大
中值: np.median(t, axis=None)
最大值: t.max(axis=None)
最小值: t.min(axis=None)
极值:np,ptp(t, axis=None) 即最大值和最小值之差
标准差:t.std(axis=None)
说明: 标准差是一组数据平均值分散在程度中的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值接近平均值反映出数据的波动稳定情况,越大表示波动越大,越不稳定
默认返回多为数组的全部统计结果,如果指定axis,则返回一个当前轴上的结果
import numpy as np
def temp_nan(t):
for i in range(t.shape[-1]):
"""查看当前是哪一列"""
temp_col = t[:, i]
nan_number = np.count_nonzero(temp_col != temp_col) # nan数列的数量
if nan_number != 0: # 当nan不等于0时,说明此数列有nan值
temp_nan_col = temp_col[temp_col == temp_col] # 当前这一列不为nan的数列(除nan以外的值)
temp_number = temp_nan_col.mean() # 取均值
temp_col[np.isnan(temp_col)] = temp_number # 将nan的值赋值为均值
return t
if __name__ == '__main__':
t = np.arange(24).reshape((4, 6)).astype(float)
t[1, 2:] = np.nan # 将第三行,第三到四列中的交点值变为nan值
print(t)
print("*"*100)
t = temp_nan(t)
print(t)
这里我画了一个numpy学习的思维导图
最后把我认为比较重要的问题列出来一下
numpy 学习小结
持以进步,恒以为功!