文章目录
1. 什么是numpy
一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算
2. numpy 数组创建
使用numpy生成数组,得到ndarray类型的数据
import numpy as np
t1 = np.array([1,2,3])
t2 = np.array(range(10))
t3 = np.arange(4,10,2) #[4 6 8] 三个参数:起始、终止、步长
print(type(t3)) #<class 'numpy.ndarray'>,数组的数据类型为nd.array
print(t3.dtype) #int32 得到数组里面元素的数据类型
3. 数据类型的操作
3.1 numpy中的float类型
t4 = np.array(range(1,4),dtype='float32')
print(t4) #[1. 2. 3.]
print(t4.dtype)#float32
or
t4 = np.array(range(1,4),dtype=float)
print(t4) #[1. 2. 3.]
print(t4.dtype)#float64
3.2 numpy中的bool类型
t5 = np.array([1,1,0,1,0,0],dtype=bool)
print(t5) #[ True True False True False False]
print(t5.dtype) #
3.3 调整数据类型
astype()方法有返回值,需要变量接收
t5 = t5.astype('int8')
print(t5) #[1 1 0 1 0 0]
print(t5.dtype) #int8
3.4 numpy中的小数
同样,np.round()函数有返回值,需要变量接收
import random
t7 = np.array([random.random() for i in range(10)])
print(t7)
print(t7.dtype)
# [0.67970087 0.50769859 0.78377386 0.57829548 0.96005045 0.83328581
# 0.0682913 0.11819872 0.67928698 0.41542126]
# float64
t8 = np.round(t7,2) #或者 t8 = t7.round(2)
print(t8)
# [0.68 0.51 0.78 0.58 0.96 0.83 0.07 0.12 0.68 0.42]
4. 数组的形状
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
# [[1 2 3]
# [4 5 6]]
print(t2.shape) #(2, 3)
t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
# [[[ 1 2 3]
# [ 4 5 6]]
#
# [[ 7 8 9]
# [10 11 12]]]
print(t3.shape) #(2, 2, 3)
- 使用reshape()方法,注意参数是一个tuple
t4 = np.arange(12)
print(t4)
# [ 0 1 2 3 4 5 6 7 8 9 10 11]
t5 = t4.reshape((3,4)) #reshape有返回值,t4本身没有发生变化
print(t5)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
t6 = np.arange(24).reshape((2,3,4))
print(t6)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
t7 = t6.reshape((24,)) #转成一维数组
print(t7)
5. 数组的计算
5.1 数组和数的计算
5.2 数组和数组计算
5.2.1 相同维度的数组之间进行计算
对应位置的数字进行计算
5.2.2 不同维度的数组之间进行计算
某一维度形状一样,可以进行计算
- 尽管数组维度不同,但每行的元素个数相同,每一行进行运算
- 尽管数组维度不同,但每列的元素个数相同,每一列进行运算
- 若行、列中的元素都不相同,则报错
6. 轴
在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴
有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值
那么问题来了:
在前面的知识,轴在哪里?
回顾np.arange(0,10).reshape((2,5)),reshpe中2表示0轴长度(包含数据的条数)为2,1轴长度为5,2X5一共10个数据
6.1 二维数组的轴
6.2 三维数组的轴
7. numpy数据读取
7.1 CSV文件介绍
CSV:Comma-Separated Value,逗号分隔值文件
显示:表格状态
源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录
由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,为了方便教学,我们会经常操作csv格式的文件,但是操作数据库中的数据也是很容易的实现
7.2 数据读取函数 loadtxt()
np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
- skiprows 跳过第一行就写1,默认为0即不跳过任何一行
import numpy as np
us_file_path = 'US_video_data_numbers.csv'
gb_file_path = 'GB_video_data_numbers.csv'
t1 = np.loadtxt(us_file_path,delimiter=",",dtype='int64',unpack=True)
t2 = np.loadtxt(us_file_path,delimiter=',',dtype='int64')
print(t1)
print('#'*100)
print(t2)
- unpack = True 按照对角线旋转,转置如下所示,:行变成列,列变成行
7.3 转置
8. numpy中的索引和切片
8.1 取行数据
# 取一行
print(t2[2]) #一维数组(4,)
print('#'*100)
#取连续的多行
print(t2[2:5]) #二维数组
print('#'*100)
#取不连续的多行
print(t2[[2,5,10]])
#通用格式
print(t2[2:4,:]) #逗号前为行,逗号后为列,列的位置用冒号表示每一列都要
8.2 取列数据
#取一列
print(t2[:,1]) #结果转换成行变成一维数组
#取连续的多列
print(t2[:,1:3]) #结果为索取的多列
#取不连续的多列
print(t2[:,[1,2,3]])
8.3 取多行多列
#具体数字取值,取第3行,第4列的值
a = t2[2,3]
print(a) #170708
print(type(a)) # <class 'numpy.int64'>
#取第3行到第5行,第2列到第4列的结果,取的是交叉点的位置
b = t2[2:5,1:4]
# [[576597 39774 170708]
# [ 24975 4542 12829]
# [ 96666 568 6666]]
#取多个不相邻的点
#选出来的结果是 (0,0) (2,1) (2,3)
c = t2[[0,2,2],[0,1,3]]
print(c)
# [4394029 576597 170708] #结果为对应位置元素所组成的一维数据
9. numpy中数值的修改
9.1 将数组中的元素批量修改成某一个值
import numpy as np
np.random.seed(1)
t1 = np.random.randint(0,20,(4,5))
print(t1)
# [[ 5 11 12 8 9]
# [11 5 15 0 16]
# [ 1 12 7 13 6]
# [18 5 18 11 10]]
t1[0:2,0:2] = 4 #直接对原数组进行修改
print(t1)
# [[ 4 4 12 8 9]
# [ 4 4 15 0 16]
# [ 1 12 7 13 6]
# [18 5 18 11 10]]
9.2 依据布尔索引进行修改
9.2.1 布尔索引
np.random.seed(1)
arr1 = np.random.randint(1,20,(4,5))
print(arr1)
arr1 = arr1<10
print(arr1)
# [[ 6 12 13 9 10]
# [12 6 16 1 17]
# [ 2 13 8 14 7]
# [19 6 19 12 11]]
# [[ True False False True False]
# [False True False True False]
# [ True False True False True]
# [False True False False False]]
9.2.2 利用布尔索引修改
np.random.seed(1)
arr1 = np.random.randint(1,20,(4,5))
print(arr1)
# [[ 6 12 13 9 10]
# [12 6 16 1 17]
# [ 2 13 8 14 7]
# [19 6 19 12 11]]
arr1[arr1<10] = 3
print(arr1)
# [[ 3 12 13 3 10]
# [12 3 16 3 17]
# [ 3 13 3 14 3]
# [19 3 19 12 11]]
9.2.3 numpy中三元运算符
np.random.seed(1)
arr1 = np.random.randint(1,20,(4,5))
print(arr1)
# [[ 6 12 13 9 10]
# [12 6 16 1 17]
# [ 2 13 8 14 7]
# [19 6 19 12 11]]
arr1 = np.where(arr1<10,0,20) #where有返回值,需要变量接收
print(arr1)
# [[ 0 20 20 0 20]
# [20 0 20 0 20]
# [ 0 20 0 20 0]
# [20 0 20 20 20]]
9.2.4 clip 裁剪
np.random.seed(1)
arr1 = np.random.randint(1,20,(4,5))
print(arr1)
# [[ 6 12 13 9 10]
# [12 6 16 1 17]
# [ 2 13 8 14 7]
# [19 6 19 12 11]]
arr1 = arr1.clip(10,18)
print(arr1)
# [[10 12 13 10 10]
# [12 10 16 10 17]
# [10 13 10 14 10]
# [18 10 18 12 11]]
10. 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)
10.1 nan注意的点
- 验证 np.nan != np.nan
print(np.nan != np.nan) #True
print(np.nan == np.nan) #False
- 判断 np.nan 的个数, 利用 count_nonzero 函数
利用 np.nan != np.nan
arr1 = np.random.randint(1,20,(4,5))
print(arr1)
# [[ 6 12 13 9 10]
# [12 6 16 1 17]
# [ 2 13 8 14 7]
# [19 6 19 12 11]]
arr1 = arr1.astype(float)
arr1[3,3] = np.nan
print(arr1)
arr1[:,0] = 0
print(arr1)
# [[ 0. 12. 13. 9. 10.]
# [ 0. 6. 16. 1. 17.]
# [ 0. 13. 8. 14. 7.]
# [ 0. 6. 19. nan 11.]]
print(np.count_nonzero(arr1)) #16
print(arr1!=arr1)
# [[False False False False False]
# [False False False False False]
# [False False False False False]
# [False False False True False]]
print(np.count_nonzero(arr1!=arr1)) #1
- 利用 np.isnan() 函数
print(np.isnan(arr1))
# [[False False False False False]
# [False False False False False]
# [False False False False False]
# [False False False True False]]
print(np.count_nonzero(np.isnan(arr1))) #1
- 和nan的计算
t3 = np.arange(12).reshape((3,4))
print(t3)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.sum(t3,axis=0)) #[12 15 18 21] 0轴加和,计算行上的结果,和行的形状一致
print(np.sum(t3,axis=1)) #[ 6 22 38] 1轴加和,计算列上的结果,和列的形状一致
print(np.sum(arr1,axis=0)) #[ 0. 37. 56. nan 45.]
10.2 替换nan
那么问题来了,在一组数据中单纯的把nan替换为0,合适么?会带来什么样的影响?
比如,全部替换为0后,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行
那么问题来了:
如何计算一组数据的中值或者是均值
如何删除有缺失数据的那一行(列)[在pandas中介绍]
10.3 numpy中常用统计函数
10.4 nan的处理–计算每一列均值
import numpy as np
t1 = np.arange(12).reshape((3,4)).astype(float)
t1[1,2:] = np.nan
def fill_ndarray(t1):
for i in range(t1.shape[1]): #遍历每一列
temp_col = t1[:,i] #当前的一列
nan_num = np.count_nonzero(temp_col != temp_col)
if nan_num != 0: #不为0,说明当前这一列中有nan
temp_not_nan_col = temp_col[temp_col==temp_col] #当前一列不为nan的array
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean() #选中当前为nan的位置,把值赋值为不为nan的均值
return t1
t1 = fill_ndarray(t1)
print(t1)
# [[ 0. 1. 2. 3.]
# [ 4. 5. 6. 7.]
# [ 8. 9. 10. 11.]]
11 练习
美国youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图
import numpy as np
from matplotlib import pyplot as plt
t_us_comments = np.loadtxt('US_video_data_numbers.csv',delimiter=',',skiprows=1,usecols=3,dtype=int)
t_us_comments = t_us_comments[t_us_comments<5000] #删掉部分数据
d = 50
bin_nums = (t_us_comments.max()-t_us_comments.min())//d
plt.hist(t_us_comments,bin_nums)
plt.show()
希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图
import numpy as np
from matplotlib import pyplot as plt
t_GB = np.loadtxt('GB_video_data_numbers.csv',delimiter=',',skiprows=1,dtype=int)
t_GB = t_GB[t_GB[:,1]<=50000] #选择喜欢数比5万小的
t_GB_comments = t_GB[:,-1]
t_GB_likes = t_GB[:,1]
plt.scatter(t_GB_comments,t_GB_likes)
plt.show()
12 数据的拼接
数组水平或者竖直拼接很简单,但是拼接之前应该注意什么?
竖直拼接的时候:每一列代表的意义相同!!!否则牛头不对马嘴
如果每一列的意义不同,这个时候应该交换某一组的数的列,让其和另外一类相同
那么问题来了?
如何交换某个数组的行或者列呢?
练习:
现在希望把之前案例中两个国家的数据方法一起来研究分析,同时保留国家的信息(每条数据的国家来源),应该怎么办
import numpy as np
#加载国家数据
us_data = np.loadtxt('US_video_data_numbers.csv',delimiter=',',dtype=int)
uk_data = np.loadtxt('GB_video_data_numbers.csv',delimiter=',',dtype=int)
#添加国家信息
#方法:构造全为0或1的数据
zero_data = np.zeros((us_data.shape[0],1)).astype(int)
one_data = np.ones((uk_data.shape[0],1)).astype(int)
#分别添加一列全为0,1的数组
us_data = np.hstack((us_data,zero_data))
uk_data = np.hstack((uk_data,one_data))
#拼接两组数据
final_data = np.vstack((us_data,uk_data))
print(final_data)
13 numpy其他方法
1.获取最大值最小值的位置
1)np.argmax(t,axis=0)
2) np.argmin(t,axis=1)
2.创建一个全0的数组: np.zeros((3,4))
3.创建一个全1的数组:np.ones((3,4))
4.创建一个对角线为1的正方形数组(方阵):np.eye(3)
xt(‘GB_video_data_numbers.csv’,delimiter=’,’,dtype=int)
#添加国家信息
#方法:构造全为0或1的数据
zero_data = np.zeros((us_data.shape[0],1)).astype(int)
one_data = np.ones((uk_data.shape[0],1)).astype(int)
#分别添加一列全为0,1的数组
us_data = np.hstack((us_data,zero_data))
uk_data = np.hstack((uk_data,one_data))
#拼接两组数据
final_data = np.vstack((us_data,uk_data))
print(final_data)
# 13 numpy其他方法
1.获取最大值最小值的位置
1)np.argmax(t,axis=0)
2) np.argmin(t,axis=1)
2.创建一个全0的数组: np.zeros((3,4))
3.创建一个全1的数组:np.ones((3,4))
4.创建一个对角线为1的正方形数组(方阵):np.eye(3)