什么是数据分析:数据分析是用适当的方法对收集来的大量数据进行分析,帮助人们作出判断,以便采取适当行动。
数据分析的流程:
基础
-
conda环境安装
- conda:data science package & environment manager
-
创建环境:conda create-- name 环境名 python=3
-
切换环境:
- windows:sctivate 环境名
- Linux/macos:source activate python3
官网地址:https://www.anaconda.com/download
jupyter notebook
一款编程、文档、笔记、展示软件
启动:jupyter notebook
matplotlib
能将数据进行可视化,更直观的呈现;主要做数据可视化图表,matlab能做的事情,matplotlib都能做,是模仿matlab构建
折线图
折线图用法示例:
from matplotlib import pyplot as plt
from random import randint
import matplotlib
from matplotlib import font_manager
x = range(2,26,2)
y = [randint(5,10) for _ in range(12)]
fig = plt.figure(figsize=(20,8), dpi=80) #设置图片大小:全局
# plt.xticks(x) #设置x轴刻度:按照x的数值值显示,这里的x是上面的数据
# plt.xticks([x for x in range(0,26)]) #刻度是输入哪一段显示哪一段
#matplotlib默认不支持中文,所以上面的中文无法显示
"""设置字体的方式一:
font = {'family' : 'monospace',
'weight' : 'bold',
'size' : 20
}
matplotlib.rc('font',**font) #通过此方法可以对字体进行设置从而使其支持中文,具体使用方法查看源码即可
#注意:family可能用不了,如果用不了,可以用下面的第二种方法:直接使用字体的路径
"""
"""设置字体的方式二:实例化font_manager"""
ft_manager = font_manager.FontProperties(fname="./msyh.ttc") #其他参数见源码
plt.xticks(x, ["我是{}".format(i) for i in x],rotation=-45,fontproperties = ft_manager) #通过这样的对应方式,使坐标轴的刻度显示为字符串
#rotation是旋转的度数
#通过指定fontproperties,实现对字体的设置
plt.yticks([y for y in range(min(y), max(y)+1)], fontproperties = ft_manager)
""""为坐标轴添加描述信息"""
plt.xlabel("时间",fontproperties = ft_manager)
plt.ylabel("温度(/℃)",fontproperties = ft_manager)
plt.title("温度变化图",fontproperties = ft_manager) #设置图表名字
"""绘制网格"""
plt.grid(alpha=0.4,linestyle="--") #默认是根据x轴和y轴的刻度绘制,网格也可以用linestyle指定样式
#通过alpha关键字指定透明度
plt.plot(x,y) #根据x和y绘制折线图
"""在一张图上绘制多个图:再plot一次即可"""
y2 = [randint(5,10) for _ in range(12)]
#使用标注哪条线是什么数据
plt.plot(x,y2,label="数据2", linestyle=':', color="red", linewidth=1) #冒号表示虚线,使用color指定颜色,color也可以使用16进制而不使用名称
#添加图例,使用了这个后,才能结合label将每条线的说明添加到图上面去
#注意:还是无法显示中文,使用prop使其显示中文
#注意:图例的显示位置是根据数据的情况自动确定的,如果要手动确定:采用lco参数,其取值见源码
#linewidth设置线条粗细:
#此外,plot也可以使用alpha参数
"""linestyle的参数:
":"
"-"
"--"
"""
plt.legend(prop=ft_manager,loc="upper left") #其他地方都是fontproperties,只有这里是prop
plt.savefig("./sig_size.png") #保存图片,必须在show之前
plt.show() #在执行程序的时候展示图形
"""
此外,还可以在图中标出最高点和最低点以及添加水印
"""
结果:
如果要绘值散点图或柱状图,直接看官方文档,copy代码然后更改x、y即可
常用统计图的对比
散点图
from matplotlib import pyplot as plt
from matplotlib import font_manager
#3月份的气温和10月份的气温
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(0,31)
x_10 = range(51,82)
ft_manager = font_manager.FontProperties(fname="./msyh.ttc")
plt.figure(figsize=(20,10), dpi=80) #绘图前必须先设置图形大小
#为了使数据分开,采用不同的x坐标
"""使用scatter方法绘制散点图,和之前绘制折线图的唯一区别之处:"""
plt.scatter(x_3,y_3, label="3月份")
plt.scatter(x_10,y_10, label="10月份")
_x = list(x_3) + list(x_10)
_xtick_labels = ["3月{}日".format(i) for i in x_3] + ["10月{}日".format(i-50) for i in x_10]
plt.xticks(_x[::3], _xtick_labels[::3], fontproperties=ft_manager, rotation=45)
#[::3]使间隔大一点
#添加描述信息
plt.xlabel("时间", fontproperties=ft_manager)
plt.ylabel("温度(/℃)", fontproperties=ft_manager)
#添加图例
plt.legend(loc="upper right", prop=ft_manager)
plt.show()
# plt.savefig("./散点图.png")
plt.close()
条形图
竖着的条型图
from matplotlib import pyplot as plt
from matplotlib import font_manager
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]
plt.figure(figsize=(20,14), dpi=80)
ft_manager = font_manager.FontProperties(fname="./msyh.ttc")
plt.bar(range(len(a)), b, width=0.3) #绘制竖着的条形图
plt.xticks(range(len(a)), a, fontproperties=ft_manager, rotation=-45)
plt.show()
横着的条形图
from matplotlib import pyplot as plt
from matplotlib import font_manager
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]
plt.figure(figsize=(20,8), dpi=80)
ft_manager = font_manager.FontProperties(fname="./msyh.ttc")
plt.barh(range(len(a)), b, height=0.3, color="darkcyan") #绘制横着的条形图
plt.yticks(range(len(a)), a, fontproperties=ft_manager)
plt.grid(alpha=0.3)
plt.show()
条形图练习:数据的对比
"""各电影的3天票房对比"""
from matplotlib import pyplot as plt
from matplotlib import font_manager
a = ["猩球崛起3:终极之战", "敦刻尔克", "蜘蛛侠:英雄归来", "战狼2"]
b_16 = [15746, 312, 4497, 319]
b_15 = [12357, 156, 2045, 168]
b_14 = [2358, 399, 2358, 362]
bar_width = 0.2
x_14 = list(range(len(a)))
"""设置x的偏移,避免重叠"""
x_15 = [i+bar_width for i in x_14]
x_16 = [i+bar_width for i in x_15]
plt.figure(figsize=(20,8), dpi=80)
plt.bar(x_14, b_14, width=bar_width, label="9月4日")
plt.bar(x_15, b_15, width=bar_width, label="9月5日")
plt.bar(x_16, b_16, width=bar_width, label="9月6日")
ft_manager = font_manager.FontProperties(fname="./msyh.ttc")
plt.legend(prop=ft_manager)
plt.xticks(x_15, a, fontproperties=ft_manager)
plt.show()
直方图
绘制直方图的数据必须是原始的,没有经过处理的
from matplotlib import pyplot as plt
from matplotlib import font_manager
plt.figure(figsize=(20,8), dpi=80)
ft_manager = font_manager.FontProperties(fname="./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 = 5 #每一个竖条的宽度
num_bins = (max(a) - min(a))//d #分的组数,即:竖条的个数
"""
注意:如果此处不能整除,就会出现数据的偏移,所以取值时,d应当能够被(max(a)-min(a))整除
或者再传一个数据参数来自己指定组矩
"""
plt.hist(a,num_bins, color="#27daf0", normed=True) #每一个竖条的高度表示在该组横轴范围内的数据个数
"""加normed=True,是让图显示为频率分布直方图,如果不加,就是频数分布直方图"""
"""
组数的计算方式:
组数=极差/组矩=(max(a)-min(a))/bin_width
"""
plt.xticks(range(min(a), max(a)+d, d)) #加d是为了保证标明最大值
plt.grid()
plt.show()
用条形图模拟直方图
from matplotlib import pyplot as plt
from matplotlib import font_manager
plt.figure(figsize=(20,8), dpi=80)
ft_manager = font_manager.FontProperties(fname="./msyh.ttc")
"""对于处理过的数据,我们无法绘制直方图,因此需要自己模拟"""
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.bar(range(len(quantity)), quantity, width=1) #width=1使条形图相连
"""关于width的源码:
width : scalar or array-like, optional
The width(s) of the bars (default: 0.8).
"""
_x = [i-0.5 for i in range(13)]
_xtick_labels = interval + [150] #加150是为了保证最后的一个数据有标签
plt.xticks(_x, _xtick_labels)
plt.grid()
plt.show()
matplotlib常见方法
- matplotlib.plot()
- matplotlib.bar()
- matplotlib.scatter() #此三个方法的主要参数为x,y
- matplotlib.hist(data, bins, normed)
其他绘图工具:
- plotly
- 百度echart
- seaborn
numpy
numpy是帮助我们处理数值型数据的,多于在大型、多维数组上执行数值运算
为什么学?
- 快速
- 方便
- 科学计算的基础库
numpy中的数据类型
数组基础
import numpy as np
"""使用numpy生成数组,得到narray类型的数据"""
t1 = np.array([1,2,3])
print(t1) #[1 2 3]
print(type(t1)) #<class 'numpy.ndarray'>
t2 = np.array(range(10)) #快速生成数组
print(t2) #[0 1 2 3 4 5 6 7 8 9]
t3 = np.arange(12) #快速生成数组
print(t3) #[ 0 1 2 3 4 5 6 7 8 9 10 11]
print(t3.dtype) #查看数组里面存储数据的类型
#int32
t4 = np.array(range(1,4), dtype="float") #手动指定数据类型,一般的数据类型有32和64,比如:float32, float64
print(t4) #[1. 2. 3.]
print(t4.dtype) #float64
t5 = np.array([1,1,0,2,0,1], dtype=bool)
print(t5) #[ True True False True False True]
print(t5.dtype) #bool
"""调整数据类型"""
t6 = t5.astype("int8")
print(t6) #[1 1 0 1 0 1]
print(t6.dtype) #int8
from random import random
t7 = np.array([random() for _ in range(10)])
print(t7) #[0.65570056 0.23071285 0.07067565 0.42988007 0.76111109 0.31635193 0.06134019 0.69227702 0.86203405 0.13788751]
print(t7.dtype) #float64
t8 = np.round(t7, 2) #保留两位小数
print(t8) #[0.66 0.23 0.07 0.43 0.76 0.32 0.06 0.69 0.86 0.14]
数组的形状
import numpy as np
t1 = np.arange(12)
print(t1.shape) #(12,)
t2 = np.array([[i for i in range(4)], [j for j in range(4)]])
print(t2)
"""
[[0 1 2 3]
[0 1 2 3]]
"""
print(t2.shape) #(2, 4),第一个值表示行数,第二个值表示列数
#t1称为一维数组,t2称为二维数组
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),有两个两行3列的数据
"""修改数组的形状"""
t4 = np.arange(12)
print(t4.reshape((3,4))) #想使其变为3行4列
#reshape对数据本身不会有改变,是返回其reshape后的数据
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
t5 = np.arange(24)
print(t5.reshape((2,3,4))) #第一个数字可以大概理解为“块”,第二数字:每块的行,第三个数字:每块的列
"""
[[[ 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(t5.reshape((24,))) #重新变为一维数组,[ 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(t5.reshape((24,1))) #变成含24个一维数组的二组数组
"""
[[ 0]
[ 1]
[ 2]
...
[23]]
"""
print(t5.reshape(1,24)) #变成含一个一维数组的二维数组, [[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]]
t5 = t5.reshape((24,1))
print(t5.shape) #(24, 1)
"""使其变为一维数组"""
t6 = t5.reshape(t5.shape[0] * t5.shape[1]) #由于shape是一个元组,所以参数的意思是行数*列数
print(t6) #[ 0 1 ... 22 23]
#或
print(t5.flatten()) #和t6相同,flatten:变扁平
"""reshape也可用不用传元组,而是直接传两个数,但是官方文档是传的元组"""
print(t6.reshape(2,12))
数组的计算
"""数组和数"""
import numpy as np
t5 = np.array(range(24))
t5 = t5.reshape(4,6)
print(t5+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(t5*2)
"""
[[ 0 2 4 6 8 10]
[12 14 16 18 20 22]
[24 26 28 30 32 34]
[36 38 40 42 44 46]]
"""
print(t5/2)
"""
[[ 0. 0.5 1. 1.5 2. 2.5]
[ 3. 3.5 4. 4.5 5. 5.5]
[ 6. 6.5 7. 7.5 8. 8.5]
[ 9. 9.5 10. 10.5 11. 11.5]]
"""
"""在numpy中可以除以0"""
# print(t5/0)
"""其中:nan:not a number, inf:infinity 无限
[[nan inf inf inf inf inf]
[inf inf inf inf inf inf]
[inf inf inf inf inf inf]
[inf inf inf inf inf inf]]
"""
"""数组和数组"""
t6 = np.arange(100,124).reshape((4,6))
print(t6 + t5) #对应的元素相加
"""
[[100 102 104 106 108 110]
[112 114 116 118 120 122]
[124 126 128 130 132 134]
[136 138 140 142 144 146]]
"""
#乘法和除法类似
print(t5*t6)
"""
[[ 0 101 204 309 416 525]
[ 636 749 864 981 1100 1221]
[1344 1469 1596 1725 1856 1989]
[2124 2261 2400 2541 2684 2829]]
"""
print(t5/t6)
"""
[[0. 0.00990099 0.01960784 0.02912621 0.03846154 0.04761905]
[0.05660377 0.06542056 0.07407407 0.08256881 0.09090909 0.0990991 ]
[0.10714286 0.11504425 0.12280702 0.13043478 0.13793103 0.14529915]
[0.15254237 0.15966387 0.16666667 0.17355372 0.18032787 0.18699187]]
"""
"""注意:numpy中不同型号的数组也可以进行计算"""
t7 = np.arange(0,6)
print(t5-t7) #t5中的每一行减去t7中的每一行
"""
[[ 0 0 0 0 0 0]
[ 6 6 6 6 6 6]
[12 12 12 12 12 12]
[18 18 18 18 18 18]]
"""
t8 = np.arange(0,4).reshape(4,1) #与t5列数相同
print(t5-t8)
"""在列上进行计算
[[ 0 1 2 3 4 5]
[ 5 6 7 8 9 10]
[10 11 12 13 14 15]
[15 16 17 18 19 20]]
"""
"""但是如果行数和列数都不相同,就无法进行计算"""
"""
总结:
数组和数进行计算:对数组的每个元素进行计算(广播机制)
相同维度的数组计算:对应的元素进行计算
数组和某一维度相同的数组进行计算:分别在该维度上进行对应元素的计算
完全不同维度的数组:不能计算
"""
"""广播原则:
如果两个数组后缘维度(即从末尾算起的维度)的轴长相符或方的长度为1,则认为他们是广播兼容的。广播会在确实和(或)长度为1的维度上进行
eg:shape为(3,3,2)的数组能够和(3,2)的数组进行计算
#上面的可以这么理解:第一个为3块,每块3行2列,而第二个是3行2列的,所以两个数组可以进行计算
#但是要注意:shape为(3,3,2)的数组可以和(3,3)的数组进行计算
#个人理解:要么从前匹配,要么从后匹配,只要能匹配上,就可以进行计算,3,3,2可以想象为3*3的两层模方,3*3可以想象为3*3的一层模方,所以对应计算两次就可以了
"""
轴
在numpy中可以理解为方向,使用0,1,2...数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴(行)和1轴(列),...
numpy读取数据
一般我们不用numpy读取数据,但是numpy有这个方法
import numpy as np
#读取数据的格式:np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)
#skiprows:跳过行数(比如有些数据第一行是标题,我们不需要)
#frame:路径
#dtype:读取为的格式
#delimiter:数据是用什么分隔开的,到时候就按照这个分隔符切割数据
#usecols:使用哪几列数据(因为我们可能不是每一列数据都需要)
#案例:读取csv格式的文件(逗号分隔值文件)
us_file_path = "US_video_data_numbers.csv"
t1 = np.loadtxt(us_file_path, dtype="int", delimiter=",", unpack=True)
"""默认是浮点数"""
"""unpack实现行列的转换,但是不常用,因为通常一行就是一条数据"""
print(t1)
"""
[[4394029 7860119 5845909 ... 142463 2162240 515000]
[ 320053 185853 576597 ... 4231 41032 34727]
[ 5931 26679 39774 ... 148 1384 195]
[ 46245 0 170708 ... 279 4737 4722]]
"""
转置
import numpy as np
t2 = np.arange(24).reshape(4,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(t2.transpose()) #除了transpose,也可以使用t2.swapaxis(1,0)
"""
[[ 0 6 12 18]
[ 1 7 13 19]
[ 2 8 14 20]
[ 3 9 15 21]
[ 4 10 16 22]
[ 5 11 17 23]]
"""
numpy的索引和切片
import numpy as np
us_file_path = "US_video_data_numbers.csv"
t1 = np.loadtxt(us_file_path, dtype="int", delimiter=",")
print(t1)
"""
[[4394029 320053 5931 46245]
[7860119 185853 26679 0]
[5845909 576597 39774 170708]
...
[ 142463 4231 148 279]
[2162240 41032 1384 4737]
[ 515000 34727 195 4722]]
"""
print(t1[2]) #取第二行数据,[5845909 576597 39774 170708]
#注意:索引还是从0开始
"""
[5845909 576597 39774 170708]
"""
print(t1[2:])
"""
[[5845909 576597 39774 170708]
[2642103 24975 4542 12829]
[1168130 96666 568 6666]
...
[ 142463 4231 148 279]
[2162240 41032 1384 4737]
[ 515000 34727 195 4722]]
"""
print(t1[[2,8,10]]) #取第2、8、10行,结果还是一个数组
"""
[[5845909 576597 39774 170708]
[1338533 69687 678 5643]
[ 859289 34485 726 1914]]
"""
"""取列"""
#通用方法[行,列]
print(t1[0,:]) #:表示我们每一个元素都要
"""
[4394029 320053 5931 46245]
"""
print(t1[:,0]) #表示每一行都要,结果还是一个一维的横向数组
"""
[4394029 7860119 5845909 ... 142463 2162240 515000]
"""
print(t1[0,[0,1,2]]) #取0行的0,1,2三个元素
"""
[4394029 320053 5931]
"""
#取连续的多列
print(t1[:,2:]) #取第三列开始的数据。ps:如果是要取第3行和第4行的数据,t1[:,2:4]
"""
[[ 5931 46245]
[ 26679 0]
[ 39774 170708]
...
[ 148 279]
[ 1384 4737]
[ 195 4722]]
"""
print(t1[[0,1],[0,3]]) #取0行0列和1行3列的两个元素,注意,结果仍为一个横向的一维数组
"""
[4394029 0]
"""
"""取数字"""
print(t1[0,0]) #取第一个数字
"""
4394029
"""
"""
PS:行和列的列中,也可以指定步长,和列表的使用方式相同[开始, 结束, 步长]
"""
numpy中数值的修改
import numpy as np
"""
取到之后修改值即可
"""
us_file_path = "US_video_data_numbers.csv"
t = np.loadtxt(us_file_path, dtype="int", delimiter=",")
print(t)
"""
[[4394029 320053 5931 46245]
[7860119 185853 26679 0]
[5845909 576597 39774 170708]
...
[ 142463 4231 148 279]
[2162240 41032 1384 4737]
[ 515000 34727 195 4722]]
"""
t[0,0] = 0
print(t)
"""
[[ 0 320053 5931 46245]
[7860119 185853 26679 0]
[5845909 576597 39774 170708]
...
[ 142463 4231 148 279]
[2162240 41032 1384 4737]
[ 515000 34727 195 4722]]
"""
t[:,2:4]=0
print(t)
"""
[[ 0 320053 0 0]
[7860119 185853 0 0]
[5845909 576597 0 0]
...
[ 142463 4231 0 0]
[2162240 41032 0 0]
[ 515000 34727 0 0]]
"""
t[t==0] = 1
print(t) #将t中所有为0的元素置为1,t[t<10]取出t中所有小于10的元素
"""
[[ 1 320053 1 1]
[7860119 185853 1 1]
[5845909 576597 1 1]
...
[ 142463 4231 1 1]
[2162240 41032 1 1]
[ 515000 34727 1 1]]
"""
#numpy的三元运算符:where[表达式,值1,值2]
t1 = np.where(t>100, 10, 100) #将t中所有大于100的元素置为10,小于等于100的元素置为100
print(t1)
"""
[[100 10 100 100]
[ 10 10 100 100]
[ 10 10 100 100]
...
[ 10 10 100 100]
[ 10 10 100 100]
[ 10 10 100 100]]
"""
"""裁剪"""
print(t.clip(11,12)) #将t中比11小的替换为11,比12大的替换为12
#注意:nan不会被替换
"""
[[11 12 11 11]
[12 12 11 11]
[12 12 11 11]
...
[12 12 11 11]
[12 12 11 11]
[12 12 11 11]]
"""
数组的拼接与交换
"""数组的拼接"""
#把两个国家的youtube数据进行分析
"""
拼接的两种方式:1. 水平拼接(np.hstack);2. 竖直拼接(np.vstack)
"""
"""数组的行列的交换"""
#行交换
import numpy as np
t = np.arange(12,24).reshape(3,4)
print(t)
"""
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
"""
t[[1,2],:] = t[[2,1],:] #交换2维数组中的2,3两行
print(t)
"""
[[12 13 14 15]
[20 21 22 23]
[16 17 18 19]]
"""
t[:,[1,2]] = t[:,[2,1]] #交换2,3两列
print(t)
""""
[[12 14 13 15]
[20 22 21 23]
[16 18 17 19]]
"""
#相当于python中a,b = b,a
小案例:数据和切片和组合
"""两个国家的youtube视频统计"""
import numpy as np
us_data = "US_video_data_numbers.csv"
uk_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的数据标记美国
zero_data = np.zeros((us_data.shape[0],1)).astype(int) #shape[0]为行数,创建一个全为0的数组
ones_data = np.ones((uk_data.shape[0],1)).astype(int) #创建一个全为1的数组
us_data = np.hstack((us_data,zero_data))
uk_data = np.hstack((uk_data,ones_data))
#拼接两组数据
final_data = np.vstack((us_data, uk_data))
print(final_data)
"""
[[4394029 320053 5931 46245 0]
[7860119 185853 26679 0 0]
[5845909 576597 39774 170708 0]
...
[ 109222 4840 35 212 1]
[ 626223 22962 532 1559 1]
[ 99228 1699 23 135 1]]
"""
numpy中的其他方法
"""numpy中的其他方法"""
#创建一个单位矩阵(方阵,对角线为1,else为0)
import numpy as np
tmp = np.eye(3)
print(tmp)
"""
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
"""
#求最大值和最小值的方法
print(np.argmax(tmp, axis=0)) #每一行上的最大值的位置
#[0 1 2]
print(np.argmin(tmp, axis=1)) #每一列上最小值的位置
#[1 0 0]
"""numpy生成随机数"""
print(np.random.randint(10, 20, (4,5))) #生成范围在10到20的(包首不包尾),4行5列的数组
# 关于seed的使用
np.random.seed(10)
#只要seed相同,生成的数据就相同
t = np.random.randint(0,20,(3,4))
print(t)
"""本例第一次生成的数据如下,然后后面每次的数据都和第一次相同
[[ 9 4 15 0 17]
[16 17 8 9 0]
[10 8 4 19 16]
[ 4 15 11 11 1]]
"""
nan
"""copy和view
a = b 完全不复制,a和b相互影响,相当于浅拷贝
a = b[:] 视图的操作,一种切片,会创建新的对象a,但是a的数据完全由b保管,他们两个的数据变化是一致的
a = b.copy() 复制,a和b互不影响
"""
"""nan和inf
什么出现nan:
1. 当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
2. 当我们做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)
inf表示正无穷,-inf表示负无穷,比如:一个数除以0,python会报错,numpy的结果就是无穷
注意点:
nan和inf都是float类型的
np.nan != np.nan(因此,如果一个数组中含有nan,那么这个数组和他本身并不相等);但是inf==inf
nan和任何值进行计算,结果都为nan
通常情况,在计算过程中,我们常常把nan的地方替换为其所在行的均值(中值)或直接删除该行
"""
import numpy as np
t = np.arange(12).reshape((3,4)).astype(float)
t[2,3] = np.nan
print(t)
"""
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. nan]]
"""
print(t == t)
"""
[[ True True True True]
[ True True True True]
[ True True True False]]
"""
t[:,0] = 0
print(t)
"""
[[ 0. 1. 2. 3.]
[ 0. 5. 6. 7.]
[ 0. 9. 10. nan]]
"""
print(np.count_nonzero(t)) #统计非0的个数
#0
print(np.isnan(t))
"""
[[False False False False]
[False False False False]
[False False False True]]
"""
print(np.sum(t)) #计算和
#nan
tmp = np.arange(12).reshape(3,4)
print(tmp)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.sum(tmp,axis=0)) #计算某个轴上对应位置的和(这里是每一行对应位置的和,即每一列的和)
"""可以这么记忆:在行上计算,得到的结果的形式就是行"""
#[12 15 18 21]
print(np.sum(tmp, axis=1))
# [ 6 22 38]
#其他方法
print(tmp.sum())
print(tmp.sum(axis=1))
print(tmp.mean())
print(tmp.mean(axis=0))
print(tmp.max())
print(tmp.min())
print(np.ptp(tmp)) #极值
print(np.ptp(tmp,axis=1))
print(tmp.std()) #标准差,反映数据的离散程度
print(tmp.std(axis=0))
"""将nan替换为均值"""
import numpy as np
t1 = np.arange(12).reshape(3,4).astype("float")
t1[1,2:] = np.nan
print(t1)
"""
[[ 0. 1. 2. 3.]
[ 4. 5. nan nan]
[ 8. 9. 10. 11.]]
"""
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的元素
mean = temp_not_nan_col.mean() #获得当前列的均值
temp_col[temp_col != temp_col] = mean
print(t1)
"""
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
"""
pandas
numpy可以帮助我们处理数值,但是pandas除了处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据
安装:pip install pandas
pandas的常用数据类型
- Series:一维,带标签数组
- DataFrame:二维,Series容器
Series
基础
import pandas as pd
import random
t = pd.Series([random.randint(0,30) for _ in range(5)]) #也可以在创建的时候指定索引(关键字:index),但是索引的长度必须和数据的长度一致
print(t)
"""
0 28
1 17
2 26
3 22
4 14
5 7
6 12
7 1
8 19
9 19
dtype: int64
"""
temp_dict = {"name":"zhang3","age":23,"tel":10086}
t3 = pd.Series(temp_dict)
print(t3)
"""键为索引
name zhang3
age 23
tel 10086
dtype: object
"""
切片和索引
import pandas as pd
temp_dict = {"name":"zhang3","age":23,"tel":10086}
t3 = pd.Series(temp_dict)
print(t3["age"]) #通过键取值
#23
print(t3[1]) #取索引为1的行的数据
# 23
print(t3[:2]) #取前两行,取出来的结果仍然为Series,因此最后还是会有dtype行(不包括在2之内)
"""
name zhang3
age 23
dtype: object
"""
print(t3[["name","age"]]) #通过键值取多组数据
"""从结果可见,取出来的结果仍然为Series数据,如果所取的键不存在,其结果就是NaN
name zhang3
age 23
dtype: object
"""
#此外,也可以通过bool索引取值
import random
t4 = pd.Series([random.randint(10,30) for _ in range(5)])
print(t4)
"""
0 21
1 12
2 30
3 11
4 19
dtype: int64
"""
print(t4[t4>20])
"""
0 21
2 30
dtype: int64
"""
for i in t3.index: #取出索引
print(i)
"""
name
age
tel
"""
print(t3.values) #取值
#['zhang3' 23 10086]
"""numpy中的很多方法,pandas都有,但是where稍有区别"""
使用数据库中的数据与DataFrame
"""使用数据库中的数据
pd.read_sql(sql_sentence, connection)
"""
"""读mongodb与DataFrame"""
from pymongo import MongoClient
client = MongoClient()
collection = client['admin']['Temp']
data = list(collection.find())
print(data)
t1 = data[-1]
t1 = pd.Series(t1)
print(t1) #但是data列表中有多条数据,且每个都为字典,不能全部转为Series
t = pd.DataFrame(data) #data为列表,里面的元素为字典
print(t)
"""部分运行结果,有行索引与列索引,为二维的结构,键为列索引,序号为行索引,没有该字段就为NaN
_id name age gender size
10 5d57f407de2a3e98a5666ac3 laowang 33.0 NaN NaN
11 5d57f407de2a3e98a5666ac4 laoli 23.0 NaN NaN
12 5d57f407de2a3e98a5666ac5 laozhao 43.0 NaN NaN
13 5d57f4671b0686824d996bba laowang 33.0 NaN NaN
14 5d57f4671b0686824d996bbb laoli 23.0 NaN NaN
"""
print(t["name"]) #只取name列数据
"""
_id name age gender size
17 5d57f488edc51c4a4544a8af laoli 23.0 NaN NaN
"""
"""对data进行筛选"""
d_list = []
for d in data:
temp = {}
temp["name"] = d.get("name")
temp["age"] = d.get("age")
temp["gender"] = d.get("gender")
d_list.append(temp)
print(pd.DataFrame(d_list))
"""部分数据
name age gender
4 Wang5 12.0 1.0
5 Liyuchun 32.0 0.0
6 Zhang3 24.0 1.0
"""
#如果结构是矩阵
import numpy as np
print(pd.DataFrame(np.arange(12).reshape((3,4)))) #也可以通过index和columns分别指定行索引与列索引,其数据类型为列表
"""运行结果如下
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
"""
DataFrame的属性和方法:
loc与iloc
import pandas as pd
df = pd.read_csv("dogNames2.csv")
new_df = df.sort_values(by="Count_AnimalName") #按照列进行排序
print(new_df) #不是就地排序
"""部分数据
Row_Labels Count_AnimalName
16212 39743 1
... ... ...
9133 MAX 1153
1149 BELLA 1195
[16213 rows x 2 columns]
"""
print(new_df.tail(2)) #取后2个
"""
Row_Labels Count_AnimalName
9133 MAX 1153
1149 BELLA 1195
"""
print(df[:10]) #取前10行
"""
Row_Labels Count_AnimalName
0 MARCH 2
1 APRIL 51
2 AUGUST 14
3 DECEMBER 4
4 SUNDAY 13
5 MONDAY 4
6 FRIDAY 19
7 JAN 1
8 JUN 1
9 JANUARY 1
"""
"""用数字取行,列标签取列"""
print(df[5:10]["Row_Labels"]) #取5-10行中的固定列
"""
5 MONDAY
6 FRIDAY
7 JAN
8 JUN
9 JANUARY
"""
"""loc与iloc"""
#loc通过标签获取数据
#iloc通过位置获取数据
import numpy as np
t3 = pd.DataFrame(np.arange(12).reshape(3,4), index=list("abc"), columns=list("WXYZ"))
print(t3)
"""
W X Y Z
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
"""
print(t3.loc["a","Z"]) #取a行Z列的数据
#3
print(t3.loc[:,"Z"]) #取Z列
"""
a 3
b 7
c 11
"""
print(t3.loc[["a","c"],:]) #取多行,多列同理
"""
W X Y Z
a 0 1 2 3
c 8 9 10 11
"""
print(t3["a":"c":]) #选择a-z行的数据,注意:包首包尾
"""
W X Y Z
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
"""
#iloc
print(t3.iloc[1,:]) #取1行
"""
W 4
X 5
Y 6
Z 7
Name: b, dtype: int32
"""
print(t3.iloc[:,0])
"""
a 0
b 4
c 8
Name: W, dtype: int32
"""
print(t3.iloc[:,[2,1]]) #取第2列和第一列
"""可以看到Y和X交换了位置
Y X
a 2 1
b 6 5
c 10 9
"""
print(t3.iloc[1:,:2]) #取1行后面的,2列前面的
"""
W X
b 4 5
c 8 9
"""
#也可以对其赋值
t3.iloc[1:,:2] = 0 #也可以=np.nan
print(t3)
"""
W X Y Z
a 0 1 2 3
b 0 0 6 7
c 0 0 10 11
"""
"""pandas的bool索引"""
print(df[(df["Count_AnimalName"]>800) & (df["Count_AnimalName"]<1000)])
"""&:与,|:或,~非
Row_Labels Count_AnimalName
2653 CHARLIE 856
3244 COCO 852
12361 ROCKY 823
"""
print(df[(df["Row_Labels"].str.len()>4) & (df["Count_AnimalName"]>700)]) #字符串方法
"""
Row_Labels Count_AnimalName
1149 BELLA 1195
2653 CHARLIE 856
8545 LUCKY 723
12361 ROCKY 823
"""
pandas的字符串方法:应用到所选列的所有字符串上
ps:对于类似split方法,我们还可以后续继续使用tolist将其转换为一个大列表
df["info".str.split("/").tolist()
缺失数据的处理
-
为空,None等,在pandas中表现为NaN
- 判断方法:
pd.isnull(df),pd.notnull(df)
- 处理方式1:删除NaN所在的行列
dropna (axis=0, how='any', inplace=False)
,any是只要有一个为nan就删,如果是all,全部为nan才删,inplace,表示是否就地修改 - 处理方式2:填充数据,
t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)
,将nan替换为均值,中位数,0;计算均值时,不会将nan计算进去
- 判断方法:
-
0
- 处理方法:
t[t==0]=np.nan
,但是并不是所有的0都需要处理,根据需求而定
- 处理方法:
数据的截取
import pandas as pd
df = pd.read_csv("dogNames2.csv")
new_df = df.sort_values(by="Count_AnimalName") #按照列进行排序
print(new_df) #不是就地排序
"""部分数据
Row_Labels Count_AnimalName
16212 39743 1
... ... ...
9133 MAX 1153
1149 BELLA 1195
[16213 rows x 2 columns]
"""
print(new_df.tail(2)) #取后2个
"""
Row_Labels Count_AnimalName
9133 MAX 1153
1149 BELLA 1195
"""
print(df[:10]) #取前10行
"""
Row_Labels Count_AnimalName
0 MARCH 2
1 APRIL 51
2 AUGUST 14
3 DECEMBER 4
4 SUNDAY 13
5 MONDAY 4
6 FRIDAY 19
7 JAN 1
8 JUN 1
9 JANUARY 1
"""
"""用数字取行,列标签取列"""
print(df[5:10]["Row_Labels"]) #取5-10行中的固定列
"""
5 MONDAY
6 FRIDAY
7 JAN
8 JUN
9 JANUARY
"""
"""loc与iloc"""
#loc通过标签获取数据
#iloc通过位置获取数据
import numpy as np
t3 = pd.DataFrame(np.arange(12).reshape(3,4), index=list("abc"), columns=list("WXYZ"))
print(t3)
"""
W X Y Z
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
"""
print(t3.loc["a","Z"]) #取a行Z列的数据
#3
print(t3.loc[:,"Z"]) #取Z列
"""
a 3
b 7
c 11
"""
print(t3.loc[["a","c"],:]) #取多行,多列同理
"""
W X Y Z
a 0 1 2 3
c 8 9 10 11
"""
print(t3["a":"c":]) #选择a-z行的数据,注意:包首包尾
"""
W X Y Z
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
"""
#iloc
print(t3.iloc[1,:]) #取1行
"""
W 4
X 5
Y 6
Z 7
Name: b, dtype: int32
"""
print(t3.iloc[:,0])
"""
a 0
b 4
c 8
Name: W, dtype: int32
"""
print(t3.iloc[:,[2,1]]) #取第2列和第一列
"""可以看到Y和X交换了位置
Y X
a 2 1
b 6 5
c 10 9
"""
print(t3.iloc[1:,:2]) #取1行后面的,2列前面的
"""
W X
b 4 5
c 8 9
"""
#也可以对其赋值
t3.iloc[1:,:2] = 0 #也可以=np.nan
print(t3)
"""
W X Y Z
a 0 1 2 3
b 0 0 6 7
c 0 0 10 11
"""
"""pandas的bool索引"""
print(df[(df["Count_AnimalName"]>800) & (df["Count_AnimalName"]<1000)])
"""&:与,|:或,~非
Row_Labels Count_AnimalName
2653 CHARLIE 856
3244 COCO 852
12361 ROCKY 823
"""
print(df[(df["Row_Labels"].str.len()>4) & (df["Count_AnimalName"]>700)]) #字符串方法
"""
Row_Labels Count_AnimalName
1149 BELLA 1195
2653 CHARLIE 856
8545 LUCKY 723
12361 ROCKY 823
"""
小案例:电影数据直方图绘制
"""电影数据直方图"""
import pandas as pd
from matplotlib import pyplot as plt
file_path = "./IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
# print(df.head(1))
# print(df.info())
#rating,runtime的分布情况
#选择图形:直方图
runtime_data = df["Runtime (Minutes)"].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)
"""注意:没有出现ticks的偏移问题"""
plt.xticks(range(min_runtime, max_runtime+5, 5))
plt.show()
案例:字符串离散化
"""字符串离散化的案例"""
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
from pprint import pprint
file_path = "IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
#统计分类的列表
# print(df.info())
temp_list = df["Genre"].str.split(",").tolist() #[[],[],[]]
# print(temp_list)
genre_list = list(set(i for j in temp_list for i in j))
# print(genre_list)
zeros_df = pd.DataFrame(np.zeros((df.shape[0], len(genre_list))), columns=genre_list)
# print(zeros_df)
#给每个电影出现分类的位置赋零
for i in range(df.shape[0]):
zeros_df.loc[i, temp_list[i]] = 1 #可以同时对多列赋值为1,i行多列
# print(zeros_df.head(3))
#统计每个分类的电影的数据和
genre_count = zeros_df.sum(axis=0) #axis=0可以省略
# print(genre_count)
genre_count = genre_count.sort_values()
# print(genre_count)
_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()
join:把索引相同的数据合并到一起(行列数不必相同)
行合并
用法:pd.DataFrame1.join(pd.DataFrame2)
merge:按照指定的列把数据按照一定的方式合并到一起
列合并
用法:pd.DataFrame1.merge(pd.DataFrame2, on="某个列的索引", how="inne(默认)/outer/left/right") #如果不指定on,就取并集,否则按照指定的列索引合并(取该列处相同的行,不相同的行舍弃,进行)
- inner:交集;outer:并集,NaN补全
- how参数指定按哪种方式合并,默认内连接(inner),如果是outer,就是外连接(没有的补NaN)
- left/right="列索引":左连接/右连接
- right_on/left_on="列索引"
分组与聚合
import pandas as pd
import numpy as np
file_path = "starbucks_store_worldwide.csv"
df = pd.read_csv(file_path)
# print(df.info())
# print(df.head(1))
grouped = df.groupby(by="Country") #如果是按照多个字段分组,参数就为列表
# print(grouped)
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000022AA1A96E08>,这个对象可以分组,可以采用聚合的方法
# print(grouped.count()) #统计数量,另外,也可以使用mean、sum等方法
# print(grouped.sum)
# for i in grouped:
# print("*" * 100)
# print(i)
# print(type(i)) #每个i都是一个tuple
# for j in i:
# print("-"*100)
# print(j)
# print(type(j)) #每个j都是一个DataFrame
country_count = grouped["Brand"].count()
print(country_count)
"""
Country
AD 1
AE 144
AR 108
AT 18
AU 22
...
"""
print(country_count["CN"]) #2734
print(country_count["US"]) #13608
#统计中国每个省份店铺的数量
china_data = df[df["Country"]=="CN"]
# print(china_data.info())
grouped = china_data.groupby(by="State/Province").count()["Brand"] #先分组,然后进行count,最后取Brand列
print(grouped)
"""原始数据里面的省份就是以数字代表的
State/Province
11 236
12 58
13 24
...
"""
其他聚合函数:
案例:按照多个条件分组
import pandas as pd
#数据按照多个条件分组
df = pd.read_csv("starbucks_store_worldwide.csv")
grouped = df["Brand"].groupby(by=[df["Country"], df["State/Province"]]).count()
print(grouped)
"""发现有两个索引(复合索引),因为是按照两个条件进行分组的,对于复合索引,可以用swaplevel来交换他们的索引(当我们需要取内层索引的数据时需要用到)
Country State/Province
AD 7 1
AE AJ 2
AZ 48
DU 82
FU 2
..
US WV 25
...
"""
print(grouped.index)
"""
MultiIndex([('AD', '7'),
('AE', 'AJ'),
('AE', 'AZ'),
...
('VN', 'SG'),
('ZA', 'GT')],
names=['Country', 'State/Province'], length=545)
"""
print(type(grouped)) #发现其数据类型为Series
print(type(df["Brand"]), type(df[["Brand"]])) #类型分别为Series和DataFrame(多一个方括号的区别)
print(df.reindex(["Starbucks", "Biu~"])) #取其中的两行,如果该行不存在,就为nan
print(df.set_index("Brand", drop=False)) #把某一列作为索引(去重后的列数据),drop默认为True,即将其作为索引后,会在列中将其删除
#set_index的时候也可以传列表,形成multiIndex
# print(df.set_index(["Country", "Store Number"]).index)
"""
Brand Store Number ... Longitude Latitude
Brand ...
Starbucks Starbucks 47370-257954 ... 1.53 42.51
Starbucks Starbucks 22331-212325 ... 55.47 25.42
"""
print(df["Country"].unique())
"""unique:去重
['AD' 'AE' 'AR' 'AT' 'AU' 'AW' 'AZ' 'BE' 'BG' 'BH' 'BN' 'BO' 'BR' 'BS'
'CA' 'CH' 'CL' 'CN' 'CO' 'CR' 'CW' 'CY' 'CZ' 'DE' 'DK' 'EG' 'ES' 'FI'
'FR' 'GB' 'GR' 'GT' 'HU' 'ID' 'IE' 'IN' 'JO' 'JP' 'KH' 'KR' 'KW' 'KZ'
'LB' 'LU' 'MA' 'MC' 'MX' 'MY' 'NL' 'NO' 'NZ' 'OM' 'PA' 'PE' 'PH' 'PL'
'PR' 'PT' 'QA' 'RO' 'RU' 'SA' 'SE' 'SG' 'SK' 'SV' 'TH' 'TR' 'TT' 'TW'
'US' 'VN' 'ZA']
"""
# print(df)
pandas时间序列
"""pandas时间序列"""
import pandas as pd
d = pd.date_range(start="20181230", end="20190131", freq="10D") #D表示天,日期中间用-或/都能识别,如果有不能识别的格式,就指定format参数,其格式就和python中的时间格式化一样
print(d)
#DatetimeIndex(['2018-12-30', '2019-01-09', '2019-01-19', '2019-01-29'], dtype='datetime64[ns]', freq='10D')
d = pd.date_range(start="20181230", periods=5, freq="D") #periods表示周期,即个数
print(d)
"""
DatetimeIndex(['2018-12-30', '2018-12-31', '2019-01-01', '2019-01-02',
'2019-01-03'],
dtype='datetime64[ns]', freq='D')
"""
关于频率的更多缩写:
重采样
from pprint import pprint
import pandas as pd
import numpy as np
df = pd.read_csv("911.csv")
# print(df.head(5))
temp_list = df["title"].str.split(":").tolist()
# pprint(temp_list)
cate_list = [i[0] for i in temp_list]
# pprint(cate_list)
df["cate"] = pd.DataFrame(np.array(cate_list).reshape((df.shape[0], 1)))
"""
重采样:指将时间序列从一个频率转化为另外一个频率进行处理的过程,高频率转低频率为降采样,反之称之为升采样
"""
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
df = pd.read_csv("911.csv")
df["timeStamp"] = pd.to_datetime(df["timeStamp"]) #转化为时间序列
df.set_index("timeStamp", inplace=True) #设置索引
# print(df.head(5))
count_by_month = df.resample("M").count()["title"] #按月重采样
# print(count_by_month)
"""部分数据
timeStamp
2015-12-31 7916
2016-01-31 13096
"""
_x = count_by_month.index
# for i in _x:
# print(dir(i))
# break #查看_x中用元素的方法
_y = count_by_month.values
time_format = "%Y-%m-%d"
_x = [i.strftime(time_format) 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()
案例:时间序列
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
df = pd.read_csv("911.csv")
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
#添加列,表示分类
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))) #因为这里要新增cate列,为了能够找到索引,我们将索引的更改放在后面执行
# print(df["cate"])
df.set_index("timeStamp", inplace=True)
plt.figure(figsize=(20, 8), dpi=80)
# print(len(df.groupby(by="cate")))
#分组
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)), _x, rotation=-45)
plt.legend(loc="best")
plt.show()
网友评论