Python数据分析
1.matplotlib
1.1 什么是matplotlib
-
能将数据进行可视化,更直观的呈现
-
使数据更加客观,更有说服力
matplotlib:最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建
1.2 plt.plot()函数详细介绍
format_string
由颜色字符、风格字符、标记字符组成
-
颜色字符
'b'
蓝色'm'
洋红色 magenta'g'
绿色'y'
黄色'r'
红色'k'
黑色'w'
白色'c'
青绿色 cyan'#008000'
RGB某颜色'0.8'
灰度值字符串- 多条曲线不指定颜色时,会自动选择不同颜色
-
风格字符
'‐'
实线'‐‐'
破折线'‐.'
点划线':'
虚线'' ' '
无线条
-
标记字符
-
'.'
点标记 -
','
像素标记(极小点) -
'o'
实心圈标记 -
'v'
倒三角标记 -
'^'
上三角标记 -
'>'
右三角标记 -
'<'
左三角标记…等等
-
1.3 直线图
例1:假设一天中每隔两个小时(range(2,26,2))的气温(℃)分别是[15,13,14.5,17,20,25,26,26,27,22,18,15]
from matplotlib import pyplot as plt
# figure图形图标的意思,在这里指的是我们要画的图
# 通过实例化一个figure并且传递参数,能够在后台自动使用该figure实例
# 在图形模糊的时候可以传入dpi参数,让图片更加清晰
# 设置图片大小
fig = plt.figure(figsize=(20,8),dpi=80)
x = range(2,26,2)
y = [15,13,14.5,17,20,25,26,26,27,22,18,15]
# 绘图
plt.plot(x,y)
# 设置x轴的刻度
_xtick_lables = [i/2 for i in range(2,49)]
# ::3 代表步长
plt.xticks(_xtick_lables[::3])
plt.yticks(range(min(y),max(y)+1))
# 保存在本地
# 可以保存为svg这种矢量图格式,放大后不会有锯齿
# plt.savefig("./t1.png")
# 展示图形
plt.show()
例2:如果列表a表示10点到12点的每一分钟的气温,如何绘制折线图观察每分钟气温的变化情况?
# _*_ coding : utf-8 _*_
# @Time : 2022/7/22
# @Author : 代浩楠
# @File : 02_matplotlib_绘制10点到12点的气温
# @Project : PycharmSpace
from matplotlib import pyplot as plt
import random
import matplotlib
from matplotlib import font_manager
# font = {
# 'family': 'MicroSoft YaHei',
# 'weight': 'bold',
# 'size': 'larger'
# }
# matplotlib.rc("font",**font)
# matplotlib.rc("font",family=font.get('family'),weight=font.get('weight'))
# 设置字体
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
x = range(0, 120)
y = [random.randint(20, 35) for i in range(120)]
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(x, y)
# 调整x轴的刻度
_x = list(x)
_xtick_lables = ["10点{}分".format(i) for i in range(60)]
_xtick_lables += ["11点{}分".format(i) for i in range(60)]
# 第一个参数:代表着x坐标轴120个刻度,步长为三
# 第二个参数:根据第一个参数来写出lable值
# rotation表示旋转的度数
plt.xticks(_x[::3], _xtick_lables[::3], rotation=45,fontproperties=my_font)
# 添加描述信息
plt.xlabel("时间",fontproperties=my_font)
plt.ylabel("温度 单位(℃)",fontproperties=my_font)
plt.title("10点到12点每分钟的气温变化情况",fontproperties=my_font)
plt.show()
例3:假设大家在30岁的时候,根据自己的实际情况,统计出来了你和你同桌各自从11岁到30岁每年交的女(男)朋友的数量如列表a和b,请在一个图中绘制出该数据的折线图,以便比较自己和同桌20年间的差异,同时分析每年交女(男)朋友的数量走势
# _*_ coding : utf-8 _*_
# @Time : 2022/7/22
# @Author : 代浩楠
# @File : 03_matplotlib_分析数据
# @Project : PycharmSpace
from matplotlib import pyplot as plt
import random
import matplotlib
from matplotlib import font_manager
# 假设大家在30岁的时候,根据自己的实际情况,统计出来了你和你同桌各自从11岁到30岁每年交的女(男)朋友的数量如列表a
# 和b,请在一个图中绘制出该数据的折线图,以便比较自己和同桌20年间的差异,同时分析每年交女(男)朋友的数量走势
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
y_1 = [1, 0, 1, 1, 2, 4, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1]
y_2 = [1, 0, 3, 1, 2, 2, 3, 3, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1]
x = range(11, 31)
plt.figure(figsize=(30,8),dpi=80)
# color表示线条颜色 linestyle表示线条形式 : 表示虚线,linewidth线条的粗细
plt.plot(x,y_1,label='自己',color='r',linestyle=':')
plt.plot(x,y_2,label='同桌',color='g')
# 设置x格式
_xticks_lables = ["{}岁".format(i) for i in range(11,31)]
plt.xticks(x,_xticks_lables,fontproperties=my_font)
# 绘制网格
plt.grid(alpha=0.4) # alpha表示透明度 网格中也可以指定线条的形状
# 添加图例
plt.legend(prop=my_font, loc=0) # 那条先表示什么,跟上面label一起用,prop=my_font显示中文,loc代表位置,根据自己和同桌来分离数据
plt.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KFXNtcxd-1659168233347)(D:\Desktop\CSDN博客\Python数据分析\image-20220723130828060.png)]
1.4 散点图
例1 假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律?
from matplotlib import pyplot as plt
from matplotlib import font_manager
# 假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律?
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
y_3 = [11, 17, 16, 11, 12, 11, 12, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18, 21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22,
22, 23]
y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17, 20, 21, 20, 22, 15, 11, 15, 5, 13, 17, 10, 11, 13,
12, 13, 6]
x_3 = range(1, 32)
x_10 = range(51, 82)
# 设置图片大小
plt.figure(figsize=(20, 8), dpi=80)
# 使用scatter方法绘制散点图,和之前绘制折线图的唯一区别
plt.scatter(x_3, y_3,label='三月份')
plt.scatter(x_10, y_10,label='十月份')
# 调整x轴的刻度
_x = list(x_3)+list(x_10)
_xtick_labels = ["3月{}日".format(i) for i in x_3]
_xtick_labels += ["十月{}日".format(i) for i in x_10]
plt.xticks(_x[::3],_xtick_labels[::3],fontproperties=my_font,rotation=45)
# 添加图例
plt.legend(loc='upper left',prop=my_font)
# 添加描述信息
plt.xlabel("时间",fontproperties=my_font)
plt.ylabel("温度",fontproperties=my_font)
plt.title("标题",fontproperties=my_font)
# 展示
plt.show()
1.5 条形图
例1:假设你获取到了2017年内地电影票房前20的电影(列表a)和电影票房数据(列表b),那么如何更加直观的展示该数据?
a = [“战狼2”,“速度与激情8”,“功夫瑜伽”,“西游伏妖篇”,“变形金刚5:最后的骑士”,“摔跤吧!爸爸”,“加勒比海盗5:死无对证”,“金刚:骷髅岛”,“极限特工:终极回归”,“生化危机6:终章”,“乘风破浪”,“神偷奶爸3”,“智取威虎山”,“大闹天竺”,“金刚狼3:殊死一战”,“蜘蛛侠:英雄归来”,“悟空传”,“银河护卫队2”,“情圣”,“新木乃伊”,]
b=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23] 单位:亿
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
x = ["战狼2", "速度与激情8", "功夫瑜伽", "西游伏妖篇", "变形金刚5:最后的骑士",
"摔跤吧!爸爸", "加勒比海盗5:死无对证", "金刚:骷髅岛", "极限特工:终极回归",
"生化危机6:终章", "乘风破浪", "神偷奶爸3", "智取威虎山", "大闹天竺",
"金刚狼3:殊死一战", "蜘蛛侠:英雄归来", "悟空传", "银河护卫队2", "情圣", "新木乃伊", ]
y = [56.01, 26.94, 17.53, 16.49, 15.45,
12.96, 11.8, 11.61, 11.28, 11.12, 10.49, 10.3, 8.75, 7.55, 7.32, 6.99, 6.88, 6.86, 6.58, 6.23]
# 设置图形大小
plt.figure(figsize=(20,10),dpi=80)
# 绘制条形图
plt.bar(x,y,width=0.13)
# 设置x轴
plt.xticks(range(len(x)),x,fontproperties=my_font,rotation=45)
plt.show()
例2:假设你知道了列表a中电影分别在2017-09-14(b_14), 2017-09-15(b_15), 2017-09-16(b_16)三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?
a = [“猩球崛起3:终极之战”,“敦刻尔克”,“蜘蛛侠:英雄归来”,“战狼2”]
b_16 = [15746,312,4497,319]
b_15 = [12357,156,2045,168]
b_14 = [2358,399,2358,362]
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
a = ["猩球崛起3:终极之战","敦刻尔克","蜘蛛侠:英雄归来","战狼2"]
b_16 = [15746,312,4497,319]
b_15 = [12357,156,2045,168]
b_14 = [2358,399,2358,362]
plt.figure(figsize=(20,8),dpi=80)
bar_width = 0.2
x_14 = list(range(len(a)))
x_15 = [i+bar_width for i in x_14]
x_16 = [i+bar_width*2 for i in x_14]
plt.bar(range(len(a)),b_14,width=bar_width,label='9月14日')
plt.bar(x_15,b_15,width=bar_width,label='9月15日')
plt.bar(x_16,b_16,width=bar_width,label='9月16日')
# 设置x轴的刻度
plt.xticks(x_15,a,fontproperties=my_font)
plt.legend(prop=my_font)
plt.show()
1.6 直方图
举例:
假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
a = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138,
131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101,
110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138,
117, 111, 78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126,
130, 126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99,
136, 123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125,
127, 105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120,
114, 105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132,
134, 156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,
123, 107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119,
133, 112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112,
135, 115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100,
154, 136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109,
141, 120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125,
126, 114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137,
92, 121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139,
113, 134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101,
110, 105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133,
101, 131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111, 111, 133, 150]
# 计算组数
d = 3 # 组距
num_bins = (max(a) - min(a)) // d
plt.figure(figsize=(20, 8), dpi=80)
# density分布占比
plt.hist(a, num_bins,density=True)
# 设置x轴的刻度
plt.xticks(range(min(a), max(a) + d, d))
# 绘制网格线
plt.grid()
plt.show()
例:在美国2004年人口普查发现有124 million的人在离家相对较远的地方工作。根据他们从家到上班地点所需要的时间,通过抽样统计(最后一列)出了下表的数据,这些数据能够绘制成直方图么?
from matplotlib import pyplot as plt
from matplotlib import font_manager
interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90] # 时间段
width = [5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60] # 组距
quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 47] # 数据
plt.figure(figsize=(20,8),dpi=80)
plt.bar(range(len(quantity)),quantity,width=1)
_x = [i-0.5 for i in range(13)]
plt.xticks(_x,interval+[150])
plt.grid(alpha=0.4)
plt.show()
2.numpy
2.1 什么是numpy
numpy一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算。
2.2 numpy的常用方法
1.使用numpy生成数组,得到ndarray的类型
import random
import numpy as np
# 使用numpy生成数组,得到ndarray数据类型
t1 = np.array([1,2,3,])
# [1 2 3]
print(t1)
# <class 'numpy.ndarray'>
print(type(t1))
t2 = np.array(range(10))
# [0 1 2 3 4 5 6 7 8 9]
print(t2)
t3 = np.arange(10)
# [0 1 2 3 4 5 6 7 8 9]
print(t3)
# <class 'numpy.ndarray'>
print(type(t3))
# int32
print(t3.dtype)
t4 = np.array(range(1,4),dtype=float)
# [1. 2. 3.]
print(t4)
# float64
print(t4.dtype)
t5 = np.array([1,1,0,1,0,0],dtype=bool)
# [ True True False True False False]
print(t5)
# <class 'numpy.ndarray'>
print(type(t5))
# 调整数据类型
t6 = t5.astype('int8')
# [1 1 0 1 0 0]
print(t6)
# <class 'numpy.ndarray'>
print(type(t6))
# numpy中的小数
t7 = np.array([random.random() for i in range(10)])
# [0.73593078 0.71967357 0.1779758 0.40511636 0.48492761 0.59916313
# 0.92514657 0.54853781 0.17200714 0.63195203]
print(t7)
# float64
print(t7.dtype)
# round取小数,2是两位
# [0.14 0.1 0.63 0.75 0.29 0.9 0.7 0.78 0.17 0.06]
t8 = np.round(t7,2)
print(t8)
2.数组的形状
# 当数组是一维时
import numpy as np
a = np.array([1, 2, 3, 4])
a.shape
a.shape[0] #数组的数量
# 当数组是二维时
c1 = np.array([[1, 2],[3,4], [5,6]])
c1.shape #行列形成元组直接输出
c1.shape[0] #读取行数
c1.shape[1] #读取列数
# 当数组是三维时
a = np.array(range(24)).reshape(2,3,4) #构建一个2×3×4的三维数组
a.shape[0]
a.shape[1]
a.shape[2]
import numpy as np
t1 = np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
# (2, 6)
# print(t1.shape)
t2 = np.array([0,1,2,3,4,5,6,7,8,9,10,11])
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# print(t2.reshape((3,4)))
t3 = np.arange(24)
t3 = t3.reshape(2,3,4)
# -1变为一维
t3 = t3.reshape(-1)
print(t3)
3.数组的计算
import numpy as np
t1 = np.arange(24).reshape(4,6)
# [[ 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(t1)
t1 = t1+2
# [[ 2 3 4 5 6 7]
# [ 8 9 10 11 12 13]
# [14 15 16 17 18 19]
# [20 21 22 23 24 25]]
print(t1)
4.numpy读取和存储数据
5.数组的转置
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如果为True,读入属性将写入不同数组变量,False只写入一个数组变量(数组转置)
t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t2 = np.loadtxt(us_file_path,delimiter=",",dtype=int)
print(t1)
print("=================")
print(t2)
t3 = np.arange(24).reshape(4,6)
# [[ 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(t3)
# [[ 0 6 12 18]
# [ 1 7 13 19]
# [ 2 8 14 20]
# [ 3 9 15 21]
# [ 4 10 16 22]
# [ 5 11 17 23]]
# 第一种方法:t3.transpose()转置数组
# print(t3.transpose())
# 第二种方法:t3.T
# print(t3.T)
# 第三种方法:t3.swapaxes(1,0)
print(t3.swapaxes(1,0))
6.numpy中的索引和切片
# 取行
# print(t2[2])
# 取连续的多行
# print(t2[2:])
# 取不连续的多行
# print(t2[[2,8,10]])
# 取列 第一列
# print(t2[:,0])
# 取连续的多列 从第二列开始取
# print(t2[:,2:])
# 取不连续的多列
# print(t2[:,[0,2]])
# 取多行多列 取第三行第四列的值
# print(t2[2,3])
# 取多行和多列,取第三行到第五行,第二列到第四列
# print(t2[2:5,1:4])
# 取多个不邻的点
# [4394029 576597]
# print(t2[[0,2],[0,1]])
print(t2[[0,2,2],[0,1,3]])
7.numpy的数组数值替换
# [[False False False False]
# [False False False True]
# [False False False False]
# print(t2<10)
# t2中小于10的替换为3
# t2[t2<10] = 3
# where(t2<10,0,10) t2中小于10的替换为0,否则替换为10
# np.where(t2 < 10, 0, 10) # numpy的三元运算符
# clip(10,18),小于10的替换为10,大于18的替换为18
# np.clip(10,18)
# 将指定数组替换为nan类型
t2 = t2.astype(float)
t2[3,3] = np.nan
8.numpy中的nan和naf
import numpy as np
# False
print(np.nan == np.nan)
t1 = np.arange(24).reshape(4, 6)
print(t1)
# 把第一列替换为0
t1[:, 0] = 0
print(t1)
t1 = t1.astype(float)
t1[3,3] = np.nan
# 查看不为0的数目
print(np.count_nonzero(t1))
# 可以统计出nan的数量
print(np.count_nonzero(t1!=t1))
# 也可以统计nan的数量
print(np.count_nonzero(np.isnan(t1)))
填充nan为列的平均值
import numpy as np
# 遍历每一列
def fill_ndarray(t1):
for i in range(t1.shape[1]):
# 将列切片
# [0. 4. 8.]
# [False False False]
# 0
# [1. 5. 9.]
# [False False False]
# 0
# [ 2. nan 10.]
# [False True False]
# 1
# [ 3. nan 11.]
# [False True False]
# 1
# 将数组的列切片
temp_col = t1[:, i]
# temp_col!=temp_col:自我判断,如果为nan就为True
# np.count_nonzero(temp_col!=temp_col) 没有true就为0,有true就为1
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
# 选中当前为nan的位置,把值赋值为不为nan的均值
temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
return t1
if __name__ == '__main__':
t1 = np.arange(12).reshape(3, 4).astype("float")
t1[1, 2:] = np.nan
print(t1)
t1 = fill_ndarray(t1)
print(t1)
9.数组的拼接
import numpy as np
t1 = np.arange(12).reshape(2,6)
print(t1)
t2 = np.array(range(12,24)).reshape(2,6)
print(t2)
# 竖直拼接
# [[ 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(np.vstack((t1,t2)))
# 水平拼接
# [[ 0 1 2 3 4 5 12 13 14 15 16 17]
# [ 6 7 8 9 10 11 18 19 20 21 22 23]]
print(np.hstack((t1,t2)))
# 行交换
# t1[[0,1],:] = t2[[1,0],:]
# [[18 19 20 21 22 23]
# [12 13 14 15 16 17]]
# print(t1)
# 列交换
# [[13 12 2 3 4 5]
# [19 18 8 9 10 11]]
t1[:,[0,1]] = t2[:,[1,0]]
print(t1)
10.numpy中的方法
现在希望把之前案例中两个国家的数据放到一起来研究分析,同时保留国家的信息(每条数据的国家来源),应该怎么办
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((结构)),创建一个全为0的数组
# us_data.shape[0]读取行数 us_data.shape[1] 读取列数
zeros_data = np.zeros((us_data.shape[0],1))
# 创建一个全为1的数组
ones_data = np.ones((uk_data.shape[0],1))
# 分别添加一列全为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)).astype(int)
print(final_data)
使用numpy中的随机方法
# 可以设定随机的相同种子数
np.random.seed(10)
# 0-20间的随机数,(3,4)的结构
t = np.random.randint(0,20,(3,4))
print(t)
11.numpy中计算统计方法
t2 = np.arange(12).reshape(3,4)
print(t2)
print(np.sum(t2))
print(np.sum(t2,axis=0))
# 计算每列的均值
print(t2.mean(axis=0))
# 计算数组的均值
print(np.median(t2))
# 计算极值
print(np.ptp(t2))
# 标准差
print(np.std(t2))
12.总结
英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量直方图
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')
# 取评论的数据 -1为最后一列
t_us_comments = t_us[:,-1]
# 选择比5000小的数据
t_us_comments = t_us_comments[t_us_comments<=5000]
# 使用matplotlib画出直方图
d = 250
bin_nums = (np.max(t_us_comments)-np.min(t_us_comments))//d
# 绘图
plt.figure(figsize=(20,8),dpi=80)
plt.hist(t_us_comments,bin_nums)
plt.show()
了解英国的youtube中视频的评论数和喜欢数的关系
from matplotlib import pyplot as plt
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'
t_us = np.loadtxt(us_file_path, delimiter=',', dtype='int')
t_uk = np.loadtxt(uk_file_path, delimiter=',', dtype='int')
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.pandas
3.1 什么是pandas
pandas是python中的第三方库,主要用来处理数据,类似于excel。
3.2 pandas常用的数据类型
1.Series 一维,带标签数组(索引)
2.DataFrame 二维
import pandas as pd
t1 = pd.Series([12,3,45,6,2])
# 0 12
# 1 3
# 2 45
# 3 6
# 4 2
# dtype: int64
# print(t1)
t2 = pd.Series([1,22,33,45,6],index=list('abcde'))
# a 1
# b 22
# c 33
# d 45
# e 6
# dtype: int64
# print(t2)
t3 = {
"name":"小红",
"age":30,
"tel":10086
}
t3 = pd.Series(t3)
# print(t3["name"])
# print(t3[0])
# print(t3[[1,2]])
print(t3[["age","tel"]])
# Index(['name', 'age', 'tel'], dtype='object')
print(t3.index)
# ['name', 'age', 'tel']
print(list(t3.index))
# ['name', 'age']
print(list(t3.index)[:2])
# ['小红' 30 10086]
print(t3.values)
# <class 'numpy.ndarray'>
print(type(t3.values))
3.3 pandas读取外部数据
import pandas as pd
# pandas读取csv中的文件
df = pd.read_csv("./dogNames2.csv")
# 读取sql
# pd.read_sql()
print(df)
3.4 pandas的dataFrame的创建
import pandas as pd
import numpy as np
# index列索引,columns行索引
t1 = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list("WXYZ"))
# W X Y Z
# a 0 1 2 3
# b 4 5 6 7
# c 8 9 10 11
print(t1)
d1 = {"name":["xiaoming","xiaogang"],"age":[20,22],"tel":[10086,10010]}
d1 = pd.DataFrame(d1)
# name age tel
# 0 xiaoming 20 10086
# 1 xiaogang 22 10010
print(d1)
d2 = [{"name":"小刚","age":22,"tel":10086},{"name":"小红","tel":10010},{"name":"小李","age":25}]
d2 = pd.DataFrame(d2)
# name age tel
# 0 小刚 22.0 10086.0
# 1 小红 NaN 10010.0
# 2 小李 25.0 NaN
print(d2)
3.5 pandas之DataFrame的描述信息
t2 = {"name":["xiaoming","xiaogang"],"age":[20,22],"tel":[10086,10010]}
t2 = pd.DataFrame(t2)
print(t2)
# 数据的列
# Index(['name', 'age', 'tel'], dtype='object')
print(t2.columns)
# 数据值
# [['xiaoming' 20 10086]
# ['xiaogang' 22 10010]]
print(t2.values)
# 数据的索引,开始、结尾、步长
# RangeIndex(start=0, stop=2, step=1)
print(t2.index)
# dtypes列的类型
# name object
# age int64
# tel int64
# dtype: object
print(t2.dtypes)
# 2 维度
print(t2.ndim)
# 头几行数据
print(t2.head())
# 尾几行数据
print(t2.tail())
# 相关信息概览:行数、列数、列索引
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 2 entries, 0 to 1
# Data columns (total 3 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 name 2 non-null object
# 1 age 2 non-null int64
# 2 tel 2 non-null int64
# dtypes: int64(2), object(1)
# memory usage: 176.0+ bytes
# None
print(t2.info())
# 描述信息
# age tel
# count 2.000000 2.000000
# mean 21.000000 10048.000000
# std 1.414214 53.740115
# min 20.000000 10010.000000
# 25% 20.500000 10029.000000
# 50% 21.000000 10048.000000
# 75% 21.500000 10067.000000
# max 22.000000 10086.000000
print(t2.describe())
import pandas as pd
import numpy as np
df = pd.read_csv("dogNames2.csv")
# print(df.head())
# print(df.info())
# dataFrame中排序的方法
# by:通过什么排序
# ascending:True为降序,False为升序
df = df.sort_values(by="Count_AnimalName",ascending=False)
# print(df.tail())
# # 前五行数据
# print(df.head(5))
# pandas取行或者取列的注意点
# 1.写括号写数组,表示取行,对行进行操作
# 2.写字符串,表示的取列索引,对列进行操作
# 取前二十行
print(df[:20])
# 求出具体的Row_Labels列
print(df["Row_Labels"])
print("------------")
# 同时选择行和列
print(df[:5]["Row_Labels"])
# loc,iloc
# loc:通过标签索引行数据
t2 = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list("WXYZ"))
# W X Y Z
# a 0 1 2 3
# b 4 5 6 7
# c 8 9 10 11
print(t2)
# 3
print(t2.loc["a","Z"])
# <class 'numpy.int32'>
print(type(t2.loc["a","Z"]))
# 去整行
print(t2.loc["a"])
# 取列
print(t2.loc[:,'Y'])
# 取多行多列
# a 0
# c 8
print(t2.loc[["a","c"],"W"])
# W Y
# a 0 2
# b 4 6
# c 8 10
print(t2.loc["a":"c",["W","Y"]])
print("=====================")
# iloc:通过位置获取行数据
# 取第一行
# W 4
# X 5
# Y 6
# Z 7
print(t2.iloc[1,:])
# 取第二列和第一列
# Y X
# a 2 1
# b 6 5
# c 10 9
print(t2.iloc[:,[2,1]])
# 取多行多列
print(t2.iloc[[0,2],[1,2]])
t2.iloc[1:,:2] = np.nan
# W X Y Z
# a 0.0 1.0 2 3
# b NaN NaN 6 7
# c NaN NaN 10 11
print(t2)
3.6 pandas之布尔索引
import pandas as pd
df = pd.read_csv("dogNames2.csv")
# 条件查询数量大于800
num = df[df["Count_AnimalName"]>=800]
print(num)
3.7 pandas之字符串方法
在这里插入图片描述
# 分割字符串
print(df["info"].str.split("/"))
# 将分割的字符串变为列表
print(df["info"].str.split("/").tolist())
3.8 缺失数据的处理
import pandas as pd
import numpy as np
t1 = pd.DataFrame(np.arange(12).reshape(3, 4), index=list('abc'), columns=list('WXYZ'))
t1.iloc[1:3, :2] = np.nan
# W X Y Z
# a 0.0 1.0 2 3
# b NaN NaN 6 7
# c NaN NaN 10 11
print(t1)
# 判断是否为NaN,若是NaN为True,否则为False
# W X Y Z
# a False False False False
# b True True False False
# c True True False False
print(pd.isnull(t1))
# 判断是否不为NaN,不为NaN就为True
# W X Y Z
# a True True True True
# b False False True True
# c False False True True
print(pd.notnull(t1))
# W这一列不为NaN的数据
# a True
# b False
# c False
print(pd.notnull(t1["W"]))
# 选择一列中为True的行
# W X Y Z
# a 0.0 1.0 2 3
print(t1[pd.notnull(t1["W"])])
# 删除NaN所在的行列,axis=0为行,axis=1为列
# W X Y Z
# a 0.0 1.0 2 3
print(t1.dropna(axis=0))
# 删除全部为NaN的行,不全部为NaN的行不删 how=all为全为NaN删,how=any为不全为NaN的删
print(t1.dropna(axis=0, how="all"))
# 将NaN的数填充
print(t1.fillna(100))
print(t1.fillna(t1.mean()))
# 处理为0的数据
t1[t1==0] = np.nan
3.9 电影数直方图
import pandas as pd
from matplotlib import pyplot as plt
file_path = 'IMDB-Movie-Data.csv'
df = pd.read_csv(file_path)
# rating,runtime分布情况
# 选择图形:直方图
runtime_data = df["Runtime (Minutes)"].values
Rating = df["Rating"].values
max_runtime = runtime_data.max()
min_runtime = runtime_data.min()
# 计算组数
num_bin = (max_runtime-min_runtime)//5
plt.figure(figsize=(20,8),dpi=80)
plt.hist(runtime_data,num_bin)
plt.xticks(range(min_runtime,max_runtime+5,5))
plt.show()
3.10 pandas常用统计方法
import pandas as pd
file_path = 'IMDB-Movie-Data.csv'
df = pd.read_csv(file_path)
# 获取电影的平均评分
print(df["Rating"].mean())
# 获取导演的人数
# set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
# .unique() 获取唯一的数据
print(len(set(df["Director"].tolist())))
print(len(df["Director"].unique()))
# 获取演员人数
actors_list = []
temp_actors_list = df["Actors"].str.split(",").tolist()
for items in temp_actors_list:
for i in items:
actors_list.append(i)
actors_num = len(set(actors_list))
print(actors_num)
3.11 字符串离散化案例
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
file_path = 'IMDB-Movie-Data.csv'
df = pd.read_csv(file_path)
# 统计分类的列表(列表嵌套列表的结构)
# [['Action', 'Adventure', 'Sci-Fi'], ['Adventure', 'Mystery', 'Sci-Fi'],
temp_list = df["Genre"].str.split(",").tolist()
# 嵌套展开双循环 set 表示不重复
genre_list = list(set([i for j in temp_list for i in j]))
# 构造全为0的数组
# Horror War Sci-Fi Action ... Family Western Thriller Crime
# 0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
# 1 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
# 2 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
# 999 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
zero_df = pd.DataFrame(np.zeros((df.shape[0],len(genre_list))),columns=genre_list)
# 给每个电影出现分类的位置赋值1 df.shape[0]选中行的数量
# loc(行,列)
for i in range(df.shape[0]):
# zeros_df.loc[0,["Sci-fi","Mucical"]] = 1
zero_df.loc[i,temp_list[i]] = 1
print(zero_df.head(5))
# 统计每个分类的电影的数量和 axis=0为行标题
genre_count = zero_df.sum(axis=0)
# print(genre_count)
# 排序
genre_count = genre_count.sort_values()
_x = genre_count.index
_y = genre_count.values
# 画图
plt.Figure(figsize=(20,8),dpi=80)
plt.bar(range(len(_x)),_y)
plt.xticks(range(len(_x)),_x)
plt.show()
3.12 数据合并
import pandas as pd
import numpy as np
t1 = pd.DataFrame(np.ones((2,4)),index=["A","B"],columns=list("abcd"))
t2 = pd.DataFrame(np.zeros((3,3)),index=["A","B","C"],columns=list("xyz"))
# a b c d
# A 1.0 1.0 1.0 1.0
# B 1.0 1.0 1.0 1.0
print(t1)
# x y z
# A 0.0 0.0 0.0
# B 0.0 0.0 0.0
# C 0.0 0.0 0.0
print(t2)
# a b c d x y z
# A 1.0 1.0 1.0 1.0 0.0 0.0 0.0
# B 1.0 1.0 1.0 1.0 0.0 0.0 0.0
print(t1.join(t2))
# x y z a b c d
# A 0.0 0.0 0.0 1.0 1.0 1.0 1.0
# B 0.0 0.0 0.0 1.0 1.0 1.0 1.0
# C 0.0 0.0 0.0 NaN NaN NaN NaN
print(t2.join(t1))
t3 = pd.DataFrame(np.zeros((3,3)),columns=list("fax"))
# f a x
# 0 0.0 0.0 0.0
# 1 0.0 0.0 0.0
# 2 0.0 0.0 0.0
print(t3)
# 按照a的值比较合并
# Columns: [a, b, c, d, f, x]
# Index: []
print(t1.merge(t3,on='a'))
t3.loc[1,"a"] = 1
# a b c d f x
# 0 1.0 1.0 1.0 1.0 0.0 0.0
# 1 1.0 1.0 1.0 1.0 0.0 0.0
print(t1.merge(t3,on='a'))
# 外连接
# a b c d f x
# 0 1.0 1.0 1.0 1.0 0.0 0.0
# 1 1.0 1.0 1.0 1.0 0.0 0.0
# 2 0.0 NaN NaN NaN 0.0 0.0
# 3 0.0 NaN NaN NaN 0.0 0.0
print(t1.merge(t3,on='a',how='outer'))
3.13 数据分组聚合
import pandas as pd
import numpy as np
file_path = 'directory.csv'
df = pd.read_csv(file_path)
# print(df.head(1))
# 通过Country进行分组
grouped = df.groupby(by="Country")
# print(grouped)
# for i in grouped:
# print(i)
# 调用聚合的方法
country_count = grouped["Brand"].count()
print(country_count["CN"])
# 统计中国每个省店铺的数量
china_data = df[df["Country"]=='CN']
# 根据每个省进行分组,查看Brand的数量
grouped = china_data.groupby(by="State/Province").count()["Brand"]
# 数据按照多个条件进行分组
grouped = df["Brand"].groupby(by=[df["Country"],df["State/Province"]])
# print(grouped.count())
# df["Brand"] 是一个数组,但是df[["Brand"]]是一个series数据,会有index和column
grouped1 = df[["Brand"]].groupby(by=[df["Country"],df["State/Province"]]).count()
print(grouped1)
3.14 数据索引的学习
import pandas as pd
import numpy as np
file_path = 'directory.csv'
df = pd.read_csv(file_path)
grouped1 = df[["Brand"]].groupby(by=[df["Country"],df["State/Province"]]).count()
# 索引的方法和属性
# print(grouped1.index)
t1 = pd.DataFrame(np.ones((2,4)),index=list("AB"),columns=list("abcd"))
print(t1)
# Index(['A', 'B'], dtype='object')
print(t1.index)
t1.index = ["a","b"]
# Index(['a', 'b'], dtype='object')
print(t1.index)
# a b c d
# a 1.0 1.0 1.0 1.0
# f NaN NaN NaN NaN
print(t1.reindex(["a","f"]))
# 指定某一列作为索引
# Float64Index([1.0, 1.0], dtype='float64', name='a') drop = False,.unique是不重复
# Float64Index([1.0], dtype='float64', name='a')
print(t1.set_index("a",drop=False).index.unique())
3.15 数据分组聚合练习和总结
import pandas as pd
import numpy as np
a = pd.DataFrame({'a': range(7),'b': range(7, 0, -1),'c': ['one','one','one','two','two','two', 'two'],'d': list("hjklmno")})
b = a.set_index(["c","d"])
# a b c d
# 0 0 7 one h
# 1 1 6 one j
# 2 2 5 one k
# 3 3 4 two l
# 4 4 3 two m
# 5 5 2 two n
# 6 6 1 two o
# print(a)
# a b
# c d
# one h 0 7
# j 1 6
# k 2 5
# two l 3 4
# m 4 3
# n 5 2
# o 6 1
# print(b)
c = b["a"]
# c d
# one h 0
# j 1
# k 2
# two l 3
# m 4
# n 5
# o 6
# 1
# print(c["one"]["j"])
d = a.set_index(["d","c"])["a"]
# d c
# h one 0
# j one 1
# k one 2
# l two 3
# m two 4
# n two 5
# o two 6
# print(d)
# MultiIndex([('h', 'one'),
# ('j', 'one'),
# ('k', 'one'),
# ('l', 'two'),
# ('m', 'two'),
# ('n', 'two'),
# ('o', 'two')],
# names=['d', 'c'])
# print(d.index)
# d
# h 0
# j 1
# k 2
# Name: a, dtype: int64
# print(d.swaplevel()["one"])
# a 0
# b 7
# Name: h, dtype: int64
print(b.loc["one"].loc["h"])
1.使用matplotlib呈现出店铺总数排名前10的国家
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
file_path = 'starbucks_store_worldwide.csv'
df = pd.read_csv(file_path)
# 使用matplotlib呈现出店铺总数排名前10的国家
# 准备数据
data1 = df.groupby(by="Country").count()["Brand"].sort_values(ascending=False)[:10]
# print(data1)
_x = data1.index
_y = data1.values
plt.figure(figsize=(20,8),dpi=80)
plt.bar(_x,_y)
plt.show()
2.使用matplotlib呈现出每个中国每个城市的店铺数量
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')
file_path = 'starbucks_store_worldwide.csv'
df = pd.read_csv(file_path)
df = df[df["Country"]=="CN"]
# 查询城市店铺数量
data1 = df.groupby(by="City").count()["Brand"].sort_values(ascending=False)[:25]
# 使用matplotlib呈现出每个中国每个城市的店铺数量
plt.figure(figsize=(20,8),dpi=80)
_x = data1.index
_y = data1.values
plt.bar(_x,_y,width=0.3,color="orange")
plt.xticks(range(len(_x)),_x,fontproperties=my_font)
plt.show()
现在我们有全球排名靠前的10000本书的数据,那么请统计一下下面几个问题:
1.不同年份书的数量
2.不同年份书的平均评分情况
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
# 现在我们有全球排名靠前的10000本书的数据,那么请统计一下下面几个问题:
file_path = 'books.csv'
df = pd.read_csv(file_path)
# 查找original_publication_year不为nan的数据
# data1 = df[pd.notnull(df["original_publication_year"])]
# # 1.不同年份书的数量
# grouped = data1.groupby(by="original_publication_year").count()["title"]
# 2.不同年份书的平均评分情况
# 去除original_publication_year列中nan的行
data1 = df[pd.notnull(df["original_publication_year"])]
# 计算机平均评分
grouped = data1["average_rating"].groupby(by=data1["original_publication_year"]).mean()
print(grouped)
_x = grouped.index
_y = grouped.values
plt.figure(figsize=(20,8),dpi=80)
plt.plot(_x,_y)
plt.show()
3.16 pandas时间序列
现在我们有2015到2017年25万条911的紧急电话的数据,请统计出出这些数据中不同类型的紧急情况的次数,如果我们还想统计出不同月份不同类型紧急电话的次数的变化情况,应该怎么做呢?
第一种方法:
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from numpy import shape
df = pd.read_csv("911.csv")
# 获取分类
temp_list = df["title"].str.split(": ").tolist()
cate_list = list(set([i[0] for i in temp_list]))
# ['Traffic', 'Fire', 'EMS']
# 构造全为0的数组
zeros_df = pd.DataFrame(np.zeros((df.shape[0],len(cate_list))),columns=cate_list)
# 赋值
for cate in cate_list:
zeros_df[cate][df["title"].str.contains(cate)] = 1
sum_ret = zeros_df.sum(axis=0)
# print(sum_ret)
第二种方法:
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from numpy import shape
df = pd.read_csv("911.csv")
# 获取分类
temp_list = df["title"].str.split(": ").tolist()
cate_list = [i[0] for i in temp_list]
cate_df = pd.DataFrame(np.array(cate_list).reshape((df.shape[0],1)),columns=["cate"])
df["cate"] = cate_df
print(df.groupby(by="cate").count()["title"])
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from numpy import shape
# freq="D" day表示天
# DatetimeIndex(['2017-12-30', '2018-01-09', '2018-01-19', '2018-01-29'], dtype='datetime64[ns]', freq='10D')
day = pd.date_range(start="20171230",end="20180131",freq="10D")
print(day)
1.统计出911数据中不同月份电话次数的变化情况
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
# 统计出911数据中不同月份电话次数的变化情况
# 统计出911数据中不同月份不同类型的电话的次数的变化情况
df = pd.read_csv("911.csv")
df["timeStamp"]=pd.to_datetime(df["timeStamp"])
# inplace=False(默认)表示原数组不变,对数据进行修改之后结果给新的数组。
# inplace=True表示直接在原数组上对数据进行修改。
df.set_index("timeStamp",inplace=True)
# 统计出911数据中不同月份电话次数的变化情况
count_by_month = df.resample("M").count()["title"]
_x = count_by_month.index
_y = count_by_month.values
_x = [i.strftime("%Y%m%d") for i in _x]
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y)
plt.xticks(range(len(_x)),_x,rotation=45)
plt.show()
2.统计出911数据中不同月份不同类型的电话的次数的变化情况
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
# 统计出911数据中不同月份不同类型的电话的次数的变化情况
df = pd.read_csv("911.csv")
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
plt.figure(figsize=(20, 8), dpi=80)
# 添加列,表示分类
temp_list = df["title"].str.split(": ").tolist()
cate_list = [i[0] for i in temp_list]
df["cate"] = pd.DataFrame(np.array(cate_list).reshape((df.shape[0], 1)))
df.set_index("timeStamp",inplace=True)
# 分组
for group_name,group_data in df.groupby(by="cate"):
# 对不同的分类都进行绘图
count_by_month = group_data.resample("M").count()["title"]
_x = count_by_month.index
_y = count_by_month.values
_x = [i.strftime("%Y%m%d") for i in _x]
plt.plot(range(len(_x)), _y, label=group_name)
plt.xticks(range(len(_x)), _y, rotation=45)
plt.legend(loc='best')
plt.show()
3.现在我们有北上广、深圳、和沈阳5个城市空气质量数据,请绘制出5个城市的PM2.5随时间的变化情况
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
# 现在我们有北上广、深圳、和沈阳5个城市空气质量数据,请绘制出5个城市的PM2.5随时间的变化情况
file_path = "PM2.5/BeijingPM20100101_20151231.csv"
df = pd.read_csv(file_path)
# 把分开的时间字符串通过PeriodIndex转换为pandas时间类型
period = pd.PeriodIndex(year=df["year"], month=df["month"], day=df["day"], hour=df["hour"], freq="H")
df["datetime"] = period
# 把datatime设置为索引
df.set_index("datetime",inplace=True)
# 进行降采样
df = df.resample("7D").mean()
# 处理缺失数据,删除缺失数据
data = df["PM_US Post"].dropna()
data_china = df["PM_Dongsi"].dropna()
# 画图
_x = data.index
_x = [i.strftime("%Y%m%d") for i in _x]
_x_china = [i.strftime("%Y%m%d") for i in data_china.index]
_y = data.values
_y_china = data_china.values
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y,label="US_POST")
plt.plot(range(len(_x_china)),_y_china,label="CN_POST")
plt.xticks(range(0,len(_x),20),list(_x)[::20],rotation=45)
plt.legend(loc="best")
plt.show()