目录
什么是numpy?
一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算
创建数组
第一步:导入numpy模块
import numpy as np
方法1:传入列表
t1=np.array([1,2,3,])
方法2:使用range生成器
t2=np.array(range(12))
方法3:使用arange
t3=np.arange(12)
以上三种方法生成的结果都是一维数组:array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
数组的类名:type(a)
数据的类型: a.dtype
数据类型的操作
1.创建指定数据类型的数组
a=np.array(range(1,4),dtype="float32") #使用dtype="?"来指定数据的类型
2.修改数组的数据类型
a.astype("int32") #使用a.astype("?")来更改数组a的数据类型
3.修改浮点数的小数位数
b=([[0.13884917, 0.35012174, 0.49130636],
[0.2419185 , 0.92049264, 0.26606552]])
np.round(b,2) #使用np.round()将数组b里的每一个数都四舍五入保留两位小数
数组的形状
例如a=np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
查看数组的形状:a.shape ——> (2, 6)
修改数组的形状:a.reshape(3,4)
注意点:
- reshape里传入一个参数结果是一维数组,传入两个参数(行,列)表示二维数组,传入三个参数(块,行,列)表示三维数组,以此类推
- reshape修改的数组形状一定要与数组的元素个数相匹配,否则会报错更改数组的形状一定要在数组
- a.reshape有返回值,不会改变原数组a的形状
数组和数的计算
遵循numpy的广播机制,数组将加减乘除运算的数的值广播到所有的元素上面
数组与数组的计算
分两种情况:
1.两个数组形状相同时
对应位置上的元素进行加减乘除运算
2.两个数组形状不同时
二维/一维:两个数组在某一维度上(行或者列)相同,且在其中一方在另一维度缺失或者长度为1的方向进行计算
三维的:两个数组要保证有两个方向上轴长一样就可以计算,且在其中一方在另一维度缺失或者长度为1的方向上进行计算
例如:shape为(3,3,2)的数组能够和(3,2)的数组进行计算,两者行和列相同,所以在块的方向进行计算
In [40]: a=np.arange(18).reshape(3,3,2)
In [41]: a
Out[41]:
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]]])
In [43]: b=np.arange(6).reshape(3,2)
In [44]: b
Out[44]:
array([[0, 1],
[2, 3],
[4, 5]])
In [45]: a+b
Out[45]:
array([[[ 0, 2],
[ 4, 6],
[ 8, 10]],
[[ 6, 8],
[10, 12],
[14, 16]],
[[12, 14],
[16, 18],
[20, 22]]])
In [46]: a*b
Out[46]:
array([[[ 0, 1],
[ 4, 9],
[16, 25]],
[[ 0, 7],
[16, 27],
[40, 55]],
[[ 0, 13],
[28, 45],
[64, 85]]])
In [47]: arange(6).reshape(3,2)
numpy读取数据
numpy从csv文件读取数据的方法
np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
参数 | 说明 |
fname | csv文件路径 |
dtype | csv的字符串以什么数据类型读入数组中 |
delimiter | 分隔字符串,csv是逗号分隔 |
skiprows | 跳过前x行,一般跳过第一行表头 |
usecols | 读取指定的列,索引,元组类型 |
unpack | 数据转置,默认为Flase,如果为True,则每一列的数据都会转换成一行,有多少列,就会转成多少行 |
numpy中的转置
转置是一种变换,对于numpy中的数组来说,就是在对角线方向交换数据,目的也是为了更方便的去处理数据
In [1]: import numpy as np
...: t=np.arange(18).reshape(3,6)
In [2]: t
Out[2]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
#方法一:使用transpose方法
In [3]: t.transpose()
Out[3]:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
#方法二:交换轴
In [5]: t.swapaxes(1,0)
Out[5]:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
#方法三:用属性T转换
In [6]: t.T
Out[6]:
array([[ 0, 6, 12],
[ 1, 7, 13],
[ 2, 8, 14],
[ 3, 9, 15],
[ 4, 10, 16],
[ 5, 11, 17]])
Numpy中的索引和切片
import numpy as np
us_file_path = "US_video_data_numbers.csv"
uk_file_path = "GB_video_data_numbers.csv"
t1=np.loadtxt(us_file_path,delimiter=",",dtype="int")
t2=np.loadtxt(uk_file_path,delimiter=",",dtype="int",unpack=True)
# print(t1)
print(t2)
print("*"*100)
#取行(索引从0开始)
# print(t1[1]) #取单行
# print(t1[2:]) #取连续的多行
# print(t1[[2,8,10]])#取不连续的多行,分别取第3行,第9行和第11行
#取列
# print(t2[1,:]) #取第2行
# print(t2[2:,:]) #取第3行开始的连续的多行
# print(t2[:,0]) #取第1列
# #取从第3列开始的连续多列
# print(t2[:,[0,2]]) #取第1列和第3列
# a=t2[2,3] #取第3行第4列的值
# print(a)
# print(type(a))
# print(t2[2:5,1:4]) #取第3行到第5行,第2列到第4列的结果,取的是行和列交叉点的位置
c = t2[[0,2,2],[0,1,3]] #取多个不相邻的点 此处应该注意
print(c) #选出来的结果是(0,0) (2,1) (2,3)
numpy中数值的修改
numpy中布尔索引
In [7]: t=np.arange(24).reshape((4,6))
In [8]: t
Out[8]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
In [9]: t<10
Out[9]:
array([[ True, True, True, True, True, True],
[ True, True, True, True, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False]])
练习:如果我们想把t中小于10的数字替换为0,把大于20的替换为20,应该怎么做??
In [10]: t[t<10]=0
In [11]: t[t>20]=20
In [12]: t
Out[12]:
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 20, 20, 20]])
numpy中三元运算符
numpy中的clip(裁剪)
练习:将t中小于10的数替换成10,大于18的数替换成18
In [12]: t
Out[12]:
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 20, 20, 20]])
In [13]: t.clip(10,18)
Out[13]:
array([[10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 18, 18, 18, 18, 18]])
numpy中的nan和inf
nan(NAN,Nan):not a number表示不是一个数字,它是float类型
什么时候numpy中会出现nan:
- 当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
- 当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)
inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷,它是float类型
什么时候回出现inf包括(-inf,+inf)
- 比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)
numpy中的nan的注意点
numpy中常用统计函数
求和:t.sum
t.sum( axis=0) ------->列方向求和
t.sum( axis=1) ------->行方向求和
均值:t.mean(axis=None) 受离群点的影响较大
中值:np.median(t,axis=None)
最大值:t.max(axis=None)
最小值:t.min(axis=None)
极值:np.ptp(t,axis=None) 即最大值和最小值只差
标准差:t.std(axis=None)
标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值
反映出数据的波动稳定情况,越大表示波动越大,约不稳定
ndarry缺失值填充均值
#ndarry缺失值填充均值
import numpy as np
def fill_ndarry(t):
for i in range(t.shape[1]):#遍历每一列
temp_col = t[:, i] # 当前的一列
nan_num = np.count_nonzero(temp_col != temp_col) #统计当前列中nan的个数
if nan_num != 0:#不为0,说明当前这一列中有nan
temp_not_nan_col = temp_col[temp_col == temp_col]
#选中当前为nan的位置,把当前列不为nan的均值赋值给它
temp_col[np.isnan(temp_col)]=temp_not_nan_col.mean()
return t
if __name__=="__main__":
t1=np.arange(12).reshape((3,4)).astype("float32")
t1[1,1:]=np.nan
print(t1)
print("*"*100)
t1=fill_ndarry(t1)
print(t1)
练习1:英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图
#以美国youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图
# coding=utf-8
import numpy as np
from matplotlib import pyplot as plt
us_file_path = "../youtube_video_data/US_video_data_numbers.csv"
# uk_file_path = "../youtube_video_data/GB_video_data_numbers.csv"
t_us=np.loadtxt(us_file_path,delimiter=",",dtype="int")
# t_uk=np.loadtxt(uk_file_path,delimiter=",",dtype="int")
#取评论的数据
t_us_comments=t_us[:,-1]
t_us_comments=t_us_comments[t_us_comments<=5000]
print(t_us_comments.max(),t_us_comments.min())
# bin_nums传入列表
bin_nums=np.arange(t_us_comments.min(),t_us_comments.max()+1,100)
#绘图
plt.figure(figsize=(20,8),dpi=80)
plt.hist(t_us_comments,bin_nums)#组数是数组形式,不固定组距
plt.show()
练习2:希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图
# coding=utf-8
import numpy as np
from matplotlib import pyplot as plt
uk_file_path = "../youtube_video_data/GB_video_data_numbers.csv"
t_uk=np.loadtxt(uk_file_path,delimiter=",",dtype="int")
#选择喜欢数比500000小的数据,通过布尔索引来实现
t_uk=t_uk[t_uk[:,1]<=500000]
t_uk_comment=t_uk[:,-1]
t_uk_like=t_uk[:,1]
plt.figure(figsize=(20,8),dpi=80)
plt.scatter(t_uk_like,t_uk_comment)
plt.show()
数组的拼接
数组的行列交换
练习3:现在希望把之前案例中两个国家的数据方法一起来研究分析,同时保留国家的信息(每条数据的国家来源),应该怎么办
# coding=utf-8
import numpy as np
us_data = "../youtube_video_data/US_video_data_numbers.csv"
uk_data = "../youtube_video_data/GB_video_data_numbers.csv"
#加载国家数据
us_data = np.loadtxt(us_data,delimiter=",",dtype="int")
uk_data = np.loadtxt(uk_data,delimiter=",",dtype="int")
#添加国家信息
#构造全为0的数据
zeros_data =np.zeros((us_data.shape[0],1)).astype(int)
#构造全为1的数据
ones_data =np.ones((uk_data.shape[0],1)).astype(int)
#在原数据上分别添加代表国家的0和1的数组
us_data=np.hstack((zeros_data,us_data))
uk_data=np.hstack((ones_data,uk_data))
#拼接两组数据
final_data = np.vstack((us_data,uk_data))
print(final_data)
numpy生成随机数
np.random.----
1.numpy.random.seed():定义了全局种子,只要使用相同的seed,则每次产生的随机数都相同
In [11]: np.random.seed(0)
In [12]: np.random.randn(2,3)
Out[12]:
array([[ 1.76405235, 0.40015721, 0.97873798],
[ 2.2408932 , 1.86755799, -0.97727788]])
In [13]: np.random.seed(0)
In [14]: np.random.randn(2,3)
Out[14]:
array([[ 1.76405235, 0.40015721, 0.97873798],
[ 2.2408932 , 1.86755799, -0.97727788]])
In [16]: np.random.seed(1)
In [17]: np.random.randn(2,3)
Out[17]:
array([[ 1.62434536, -0.61175641, -0.52817175],
[-1.07296862, 0.86540763, -2.3015387 ]])
2. numpy.random.randint(low,high,(size))
返回指定范围的随机整数,范围区间为 [low,high),包括low,但不包括high,size为数组的形状;
In [18]: np.random.randint(10,20,(2,3))
Out[18]:
array([[15, 12, 14],
[12, 14, 17]])
3.numpy.random.uniform(low,high,(size))
返回指定范围的随机小数,范围区间为 [low,high),包括low,但不包括high,size为数组的形状;
In [20]: np.random.uniform(10,20,(2,3))
Out[20]:
array([[10.92800809, 15.18152549, 18.65020252],
[18.29146907, 18.29603359, 12.73049974]])