day76-初识数据分析
mysql中保存emoji表情需要将数据库的字符集改为utf8mb4
1数据分析定义及常见库
1.1数据分析定义
数据分析是基于商业目的,有目的的进行收集、整理、加工和分析数据,提炼有价值信息的一个过程。
过程:明确分析目的与框架、数据收集、数据处理(数据清洗、数据转换)、数据分析、数据展现和撰写报告等6个阶段。
数据类型可以分为表格型数据、多维数组(矩阵)及其他sql等类型的数据。
1.2常用库
1.numpy是python科学计算的基础包,numpy对于数值型数据,处理数据时比python内置的数据结构高效的多
2.pandas提供了快速便捷处理结构化数据的大量数据结构和函数
3.matplotlib最流行的用于绘制图表和其他二维数据可视化的python库
4.ipython和jupyter,jupyter notebook支持markdown和html编程
5.scipy一组专门解决科学计算中各种标准问题域的包的集合
6.scikit-learn通用的python机器学习工具包
7.statsmodels 包含经典统计学和经济计量学的算法
常用模块引用惯例:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import statsmodels as sm
2常用库的使用
在使用这些库之前,需要先安装环境(Anaconda软件),下载地址:https://www.anaconda.com/distribution/#macos
2.1ipython及jupyter使用
ipython使用于在python的shell中使用方式相同
在cmd窗口中直接输入jupyter notebook将会打开一个网页,在网页中可以直接编辑python程序。
要新建一个notebook,点击按钮New,选择“Python3”或“conda[默认项]”。如果是第一次, 点击空格,输⼊入一行Python代码。然后按Shift-Enter执⾏。当保存notebook时(File目录下的Save and Checkpoint),会创建一个后缀名为.ipynb的文件。在网页中在变量前或者后使⽤问号?,可以显示对象的信息。
在变量(函数)后使⽤??会显示函数的源码; np.load? 可以搜索含有load的文件;
%run命令运⾏所有的(或者所选择的)Python程序;使用%load,它将脚本(程序)导入到一个代码格中;%paste和%cpaste 函数。%paste 可以直接运⾏剪贴板中的代码;ctrl-a 将光标移动到一行的开头;ctrl-e 将光标移动到一行的末尾;ctrl-shift-v粘贴文本。
%run test3.py
np.*load*?
%load test3.py
%timeit 测量任何Python语句,例如矩阵乘法,的执⾏时间;%debug在出现异常的语句进入调试模式。
ipython中集成了matplotlib数据可视化库:如下,利用随机生成的数绘制折线图。
import numpy as np
%matplotlib
import matplotlib.pyplot as plt
plt.plot(np.random.randn(50).cumsum())
3numpy-数组和矢量计算
numpy之于数值计算特别重要的原因之一,是因为它可以高效处理大数组的数据。
NumPy是C语⾔编写的算法库可以操作内存,⽽不必进⾏类型检查或其它前期⼯作。比起Python的内置序列, NumPy数组使⽤的内存更少。NumPy的C语⾔编写的算法库可以操作内存,⽽而不必进⾏类型检查或其它前期⼯作。⽐起Python的内置序列, NumPy数组使⽤的内存更少。于NumPy的算法要⽐纯Python快10到100倍(甚⾄更快)。
3.1numpy的使用
NumPy最重要的一个特点就是其N维数组对象(即ndarray),该对象是一个快速⽽灵活的大数据集容器。可以利⽤这种数组对整块数据执⾏一些数学运算,其语法跟标量元素之间的运算一样。
import numpy as np
data = np.random.randn(2, 3) # 生成一个2行3列的数组
data * 10 #data中所有数据乘10
data + data
ndarray是一个通⽤的同构数据多维容器,所有元素必须是相同类型的。
data.dtype # 查看数据类型
data.shape # 查看几行几列
arr1.ndim #查看维度
data1 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr1 = np.array(data1) # 将列表data1转化成数组对象(ndarray)
zeros和ones分别可以创建指定⻓度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组(当内存没有被清理时,数据将是之前的数据,要使用该数组,需要自己手动初始化)。
np.zeros((3, 6)) # 创建3行6列全为0的数组
np.ones((3,5)) # 创建3行5列全为1的数组
np.empty((2, 3, 2)) # 创建一个三维数组,其中的值没有任何意义
arr2 = np.ones_like(arr1) #生成一个结构跟arr1一样的矩阵,数据全为1
b = np.full((2,4), '=') #生成一个2行4列,充填为=符号的矩阵
np.eye(5,5)生成对角线为1的5乘5,其他为0的矩阵
arr2[arr2 > arr1] #将arr2中arr2数大于arr1的数据筛选出来
arr = np.arange(10) #生成0-9的一维矩阵
np.empty返回的都是一些未初始化的垃圾值。
np.ones_like(arr1)生成一个结构跟arr1一样的矩阵,数据全为1。
np.full((2,4), '==') 生成一个2行4列,充填为==符号的矩阵
np.eye(5,5)生成对角线为1的5乘5,其他为0的矩阵
arr2[arr2 > arr1] 将arr2中arr2数大于arr1的数据筛选出来(逻辑为真的筛选出来)
在用两个矩阵查询数据时,可以用一个等长的其他矩阵作判断条件,然后得出一个等长的true、false矩阵,将该布尔矩阵作为另一个矩阵的查询对象,则可以筛选出true对应的矩阵。如arr2(arr1 == '李白')将筛选出arr1中跟李白同行的数据(必须两个矩阵等长)。
3.2ndarray的数据类型
给矩阵设置数据类型dtype
arr1 = np.array([1, 2, 3], dtype=np.float64)
给矩阵转换数据类型astype
arr = np.array([1, 2, 3, 4, 5])
float_arr = arr.astype(np.float64)
将浮点数转换成整数,则⼩数部分将会被截取删除;调⽤astype总会创建一个新的数组(一个数据的备份)。
3.3numpy数组的运算
不⽤编写循环即可对数据执⾏批量运算。NumPy⽤户称其为⽮量化(vectorization)。⼤⼩相等的数组之间的任何算术运算都会将运算应⽤到元素级。
数组与标量的算术运算会将标量值传播到各个元素;⼤⼩相同的数组之间的⽐较会⽣成布尔值数组。
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr * arr
arr - arr
1 / arr
arr * 0.5
3.4数组的索引和切片
3.4.1索引
一维数组的索引和切片跟列表的索引及切片相似。
arr = np.arange(10) # 生成0-9的数组
arr[5]
arr_slice =arr[5:8]
arr_slice[:] = 64 #对arr_slice进行全切片并全部修改为64,arr中的6-9也会变为64
arr[5:8] = 12 #对arr的6-9个数进行切片并赋值为12,arr数组值第6-9也会变成12
arr[5:8] = 12 #对arr的6-9个数进行切片并赋值为12,arr数组值第6-9也会变成12,对切片生成的新的数组中的数据进行修改,也将会同样影响到其之前在之前的数组中的值作修改。
ndarray切⽚的一份副本⽽⾮视图,就需要明确地进⾏复制操作,例如arr[5:8].copy()。ndarray中的复制都是深拷贝,而切片都是浅拷贝。
多维数组中,如果省略了后⾯的索引,则返回对象会是一个维度低一点的ndarray。标量值和数组都可以被赋值给arr3d[0]
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
old_values = arr3d[0].copy() # 即[[1, 2, 3], [4, 5, 6]]
arr3d[0] = 42 # 即arr3d[0]全置为42
arr3d[0] = old_values #arr3d[0]又重新赋值为原来的二维数组
3.4.2切片
array([[1, 2, 3],[4, 5, 6], [7, 8, 9]])
arr2d[:2] # [[1, 2, 3],[4, 5, 6]]
arr2d[:2, 1:] #[[2, 3],[5, 6]] 逗号前表示对行切片,逗号后表示对切后的片的列进行切片
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
arr = np.arange(32).reshape((8, 4))
arr.T #矩阵转置
arr2d[:2, 1:] 结果为[[2, 3],[5, 6]] 逗号前表示对行切片,逗号后表示对行切好后的片的列进行切片。
arr2d[1, :2] 表示选取第二行的前两列;arr2d[:2, 2] 选取第三列的前两行
只有冒号表示对整个进行切片
arr2d[:, :1] 结果为 [[1], [4], [7]];arr2d[:2, 1:] = 0将前两行第二列及其后的数据都置为0.
arr[[1, 5, 7, 2], [0, 3, 1, 2]] 前面为取的行的行号,后面列表是取列的列号,前后两个列表数值需一对应
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] 前面为取行的行号,后面为取列的全切片及每一列的数据重新排布
arr = np.arange(32).reshape((8, 4)) 生成8行4列,元素从0-31
arr.T矩阵转置
3.4.3布尔型索引
假设我们有一个⽤于存储数据的数组以及一个存储姓名的数组(含有重项)
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4)
data[names == 'Bob'] # 将筛选出data中的第1行、第4行的数据(与names数组对应)
data[names == 'Bob', 2:] # 对筛选出为bob的数据进行切片
data[names == 'Bob', 3] # 对筛选出为bob的数据取等4列
要选择除”bob”以外的其他值,既可以使⽤不等于符号(!=),也可以通过~对条件进⾏否定。
data[~(names == 'Bob')]
data[names != 'Bob'] # 选出不为bob的数据
mask = (names == 'Bob') | (names == 'Will')
data[mask] # 选出为bob或者will的数据
data[data < 0] = 0 # 将data中小于0的数据全部置为0
mask = (names == 'Bob') | (names == 'Will') ‘|’表或者
3.5花式索引
花式索引指利用整数数组进行索引
为了以特定顺序选取⾏⼦集,只需传⼊一个⽤于指定顺序的整数列表或ndarray即可;使⽤负数索引将会从末尾开始选取⾏
arr = np.empty((4, 3))
for i in range(4):
arr[i] = i #[[ 0., 0., 0.], [ 1., 1., 1.], [ 2., 2., 2.],[ 3., 3., 3.]]
arr[[3, 0, 1]] #[[ 3., 3., 3.],[ 0., 0., 0.], [ 1., 1., 1.] ]
arr[[-2, -3, -1]] #[[2., 2., 2.],[ 1., 1., 1.], [ 3., 3., 3.] ]
一次传⼊多个索引数组会有一点特别。它返回的是一个一维数组,其中的元素对应各个索引元组;
arr = np.arange(12).reshape((4, 3))
# arr=[[ 0., 1., 2.], [3., 4., 5.], [ 6., 7., 8.],[ 9., 10., 11.]]
# 选取的是(1,0),(2,2),(3,1),(0,2)
arr[[1, 2, 3, 0], [0, 2, 1, 2]] #[3,8,10,2]
#arr=[[3,5,4],[6,8,7],[9,11,10],[0,2,1]]
arr[[1, 2, 3, 0]][:, [0, 2, 1]]
3.6数组转置和轴对称
转置是重塑的一种特殊形式,它返回的是源数据的视图,即行变列,列变行。
arr.T表示转置
3.7利用np.dot计算矩阵内积
arr = np.random.randn(6, 3)
np.dot(arr.T, arr) # 结果是一个3乘3的矩阵
np.dot(arr, arr.T) # 结果是一个6乘6的矩阵
对于高维数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进⾏转置。
arr = np.arange(16).reshape((2, 2, 4))
arr.transpose((1, 0, 2))
arr.swapaxes(1, 2)
3.8通用函数(ufunc)
通⽤函数(ufunc):快速的元素级数组函数
arr = np.arange(10)
np.sqrt(arr) # 对数组每个元素开方
np.exp(arr) # 对e进行数组中数据的n次方
add或maximum接受2个数组(因此也叫⼆元(binary)ufunc),并返回一个结果数组
x = np.random.randn(8)
y = np.random.randn(8)
np.maximum(x, y)
maximum(x, y) 返回x和y中最大的一个数,结果为一个与x或者y等长的数组
add(x,y)对x和y求和
arr = np.random.randn(7) * 5
remainder, whole_part = np.modf(arr)
remainder, whole_part = np.modf(arr)分别将arr的小数部分和整数部分赋值给 remainder, whole_part,使之各生成两个数组。