1. 使用numpy生成数组,得到ndarray的类型
import numpy as np
import random
# 方法1:
t1 = np.array([1, 2, 3])
print(t1)
print(type(t1))
# 方法2:
t2 = np.array(range(10))
print(t2)
print(type(t2))
# 方法3:
t3 = np.arange(4, 10, 2)
print(t3)
print(type(t3))
2. numpy中的数据类型
# numpy创建ndarray同时指定数据类型
t4 = np.array(range(1, 4), dtype=float) # dtype=float dtype="float32" 都行
print(t4)
# 查看ndarray中每一个数据的类型
print(t4.dtype)
# numpy中的布尔类型
t5 = np.array([1, 1, 0, 0, 0], dtype=bool)
print(t5)
print(t5.dtype)
# 手动改变创建好的数组的数据类型
t6 = t5.astype("int8")
print(t6)
print(t6.dtype)
# numpy中的小数
t7 = np.array([random.random() for i in range(10)])
print(t7)
print(t7.dtype)
# 小数保留指定的位数
t8 = np.round(t7, 2)
print(t8)
3. 数组的形状
数组的形状主要的方法是shape和reshape方法
# 数组的形状主要的方法是shape和reshape方法
import numpy as np
# shape方法:判断数组是几行几列
a = np.array([[3, 4, 5], [6, 7, 8]])
print(a.shape) # (2, 3)
# reshape方法将数组转换为指定的维度
a = np.array(range(24))
print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
b = a.reshape((2, 3, 4))
print(b)
# b的值如下:即分为两组,每组分别是三行四列
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
print(b.shape) # (2, 3, 4) 因此当数组为三维时,三个数分别代表:组,行,列
# 将数组转换为一维数组的两种方式
# 1.reshape方法
c = np.array(range(12)).reshape(3, 4)
print(c) # c是一个二维数组
d = c.reshape(12,)
print(d) # 此时d即为一维数组,上面参数的12是3*4得来的,这里需要注意的是,不能传入(1, 12)来进行转换,否则会多一层[]
# 2.flatten方法
e = c.flatten()
print(e)
3. 数组的计算和numpy数组中的轴
# 首先任何维度的数组和数字计算是没有问题的,加减乘除都可以,会对多维数组的每一个元素都和数进行相应的运算
# 若二维数组间进行计算,那么,需要这两个数组间有一个维度是相同的,才可以进行计算,比如一个2行6列的数组和一个2行1列的数组进行计算
# ,会对每一个列进行相关的行操作。三维数组的计算则需要有一个面相同,即两个维度是相同的,比如(3,3,2)和(3,2)两个数组可以计算。
# numpy数组中的轴
# 在numpy中可以理解为方向,使用0,1,2...数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴
#
# 有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值
#
4. numpy读取数据,以及数据的索引、切片、转置
import numpy as np
us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"
# delimiter是文件中的分隔符,dtype指定读取后的数据类型,unpack表示将读取后的数据转置
# t1 = np.loadtxt(us_file_path, delimiter=",", dtype="int", unpack=True)
t2 = np.loadtxt(us_file_path, delimiter=",", dtype="int")
print(t2)
# 取第三行
# print(t2[2])
# 取连续的多行
# print(t2[2:])
# 取不连续的多行,记住多加一个[]
# print(t2[[2, 8, 10]])
# 取行数据另一种形式,逗号前面的表示行,后面的表示列。列取“:” 说明不管列,只对行做出约束
# print(t2[1,:])
# print(t2[2:,:])
# print(t2[[2,10,3],:])
# 取列
# print(t2[:,0])
# 取连续的多列
# print(t2[:,2:])
# 取不连续的多列
# print(t2[:,[0,2]])
# 取行和列:取第3行,第四列的值
# a = t2[2,3]
# print(a)
# print(type(a))
# 取多行和多列,取第3行到第五行,第2列到第4列的结果
# 取的是行和列交叉点的位置
b = t2[2:5, 1:4]
print(b)
# [[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]
# 数组的转置的几种方式,t是数据
# 1. t.transpose
# 2. t.swapaxes(1,0)
# 3. t.T
# numpy中数据的修改
# 1. 索引修改数据
# t[:, 2:4] = 0 第三列第四列置为0
#
# 2. 布尔索引
# 把数组中小于10的数置为0: t[t<10] = 0
#
# 3. 三元运算符
# 把小于10的数置为0,大于10的置为10: np.where(t<10, 0, 10)
#
# 4. clip方法
# 小于10的替换为10,大于18的替换为18: t.clip(10, 18)
#
5. 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都是是float类型的,若 a = np.inf/nan, 则type(a) = float nan注意点: 1.nan和nan之间不相等,利用这个特性,可以判断数组中nan的个数,即np.count_nonzero(t!=t),因为当t!=t时,只有nan是True 2.判断一个数字是否为nan:np.isnan(a),如果这里的a是一个数组,那么和t!=t的效果是一样的,也可以接着对nan进行赋值,如t[np.isnan(t)] = 0 3.t[np.count_nonzero(t!=t)] = 0不能起到和t[np.isnan(t)] = 0一样的效果,前者会把nan所在的整行变成0,而后者只针对于nan在的地方,将其变为nan 4.nan和任何值计算都为nan 5.通常把nan替换成0是不合适的,一般是设置为平均值,或者把这行(列)数据删去 常用统计函数 求和: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则返回一个当前轴上的结果,axis取0时代表行,1代表列,表示最后的结果按原来的行/列展示, 比如说sum方法,指定axis为0,并不是将每一行相加展示,而是将每一列相加展示到行上,实际是对列进行求和操作,其他的函数也是如此。总结来说就是,axis为0,统计列,以行的方式展示;axis为1,统计行,以列的方式展示。
import numpy as np
t = np.array(range(12)).reshape(3, 4).astype("float")
t[1, 1] = np.nan
print(t)
print(t != t)
# 给nan赋值,方法1
# t[t != t] = 0
# print(t)
# 给nan赋值,方法2
t[np.isnan(t)] = 0
print(t)
# 给nan所在的整行赋值为0
print(np.count_nonzero(t != t)) # 这里输出的是0,代表此时数组中没有nan,即下方的代码变为t[0]=0,则把第一行变为0,如果一行中有nan,那么该行为0
t[np.count_nonzero(t != t)] = 0
print(t)
6. 将nan处理为平均值
import numpy as 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) # nan的个数
if nan_num != 0: # 不为0,说明该列中有nan
# print(temp_col[temp_col == temp_col]) [ 2. 10.]、[ 3. 11.]
# print(temp_col[temp_col != temp_col]) [nan]、[nan]
# 取当前一列不为nan的其他数,如果这一列是[2, nan, 10],那么结果就是[2, 10]
temp_not_nan_col = temp_col[temp_col == temp_col]
# 选中当前的nan的位置,把均值赋值给nan
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
return t1
if __name__ == '__main__':
t1 = np.array(range(12)).reshape(3, 4).astype("float")
t1[1, 2:] = np.nan
print(t1)
t1 = fill_ndarray(t1)
print(t1)
7. 数据的拼接和行列交换
# 竖直拼接和水平拼接
# 竖直拼接:np.vstack((t1, t2)) 水平拼接:np.hstack((t1, t2))
# 竖直拼接要求两个数组的列相同,增加行的维度;而水平拼接要救两个数组的行相同,增加列的维度
#
# 行和列之间交换的方法:
# t[[1, 2], :] = t[[2, 1], :] 行交换
# t[:, [0, 2]] = t[:, [2, 0]] 列交换
#
# 案例:将两个国家播放量的数据拼接
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的列,和全为1的列,方便区分合并后的数据来源
zeros_data = np.zeros((us_data.shape[0], 1)).astype(int)
ones_data = np.ones((uk_data.shape[0], 1)).astype(int)
# 分别添加一列全为0,1的数组
us_data = np.hstack((us_data, zeros_data))
uk_data = np.hstack((uk_data, ones_data))
# 拼接两组数据
final_data = np.vstack((us_data, uk_data))
print(final_data)
8. 更多方法
# 获取最大值最小值的位置
# np.argmax(t,axis=0)
# np.argmin(t,axis=1)
# 创建一个全0的数组: np.zeros((3,4))
# 创建一个全1的数组:np.ones((3,4))
# 创建一个对角线为1的正方形数组(方阵):np.eye(3)
#
# 随机数相关
# .rand():范围从0到1
# .randn():标准正态随机数,浮点数,平均数0,标准差1
# .randint(low, high, (shape)):随机整数
# .uniform(low, high, (size)):均匀分布的数组
# .normal(loc, scale, (size)):从指定正态分布中随机抽取样本,分布中心是loc(概率分布平均值),标准差为scale,形状是size
# .seed(s):随机数种子,s不变,随机数不变
# numpy中其他的一些注意点:
# a=b 完全不复制,a和b相互影响
# a = b[:],视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的,
# a = b.copy(),复制,a和b互不影响
# 随机数方法举例如下
import numpy as np
np.random.seed(10)
t = np.random.randint(0, 20, (3, 4))
print(t)
9. 两个numpy绘图案例
1. 直方图
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"
# t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t_us = np.loadtxt(us_file_path, delimiter=",", dtype="int")
# 取评论的数据
t_us_comments = t_us[:, -1]
# 选择比5000小的数据,因为评论数的两级分化也较为严重,此时应该为了绘图效果舍弃一些数量很小的数据
t_us_comments = t_us_comments[t_us_comments <= 5000]
print(t_us_comments.max(), t_us_comments.min())
d = 50 # 在给定了5000的限制条件后,最高的评论数为4995,因此其实50不合理,应该取一个能被4995整除的数
bin_nums = (t_us_comments.max() - t_us_comments.min()) // d
# 绘图
plt.figure(figsize=(20, 8), dpi=80)
plt.hist(t_us_comments, bin_nums)
plt.show()
2. 散点图
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"
# t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t_uk = np.loadtxt(uk_file_path, delimiter=",", dtype="int")
# 选择喜欢书比50万小的数据,不能对喜欢或者评论数单独设置,否则会造成两者的数据维度不同
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()