美文网首页
数据分析

数据分析

作者: jxvl假装 | 来源:发表于2019-10-01 14:47 被阅读0次

什么是数据分析:数据分析是用适当的方法对收集来的大量数据进行分析,帮助人们作出判断,以便采取适当行动。

数据分析的流程:

在这里插入图片描述

基础

  • 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即可

常用统计图的对比

https://pan.baidu.com/s/1Xu8uVl6rclgTyqSV9hHNQA

散点图

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()
在这里插入图片描述

相关文章

网友评论

      本文标题:数据分析

      本文链接:https://www.haomeiwen.com/subject/xxluuctx.html