深度学习

深度学习入门路线

深度学习实战路线

深度学习必看书籍

前馈神经网络

总体框架

神经元

人工神经元:

激活函数性质

1
2
3
1.连续并可导的非线性函数
2.激活函数及其导数要尽可能简单,有利于提高网络计算效率
3.激活函数的导函数的值域要在一个合适的空间(不能太大也不能太小,否则会影响训练的效率和稳定性)

Sigmoid函数(S型曲线函数)

sigmoid函数的公式

1
2
3
4
5
6
1.分为logistic函数和Tanh函数
1.1 logistic函数(值域>0):
1.2 Tanh函数(值域(-1,1)):
2.sigmoid函数的性质:
2.1 sigmoid函数是饱和函数[x>-∞和x->+∞时,其f'(x)->0]
2.2 Tanh函数是零中心化的,logistic函数输出恒大于0的

sigmoid两种函数的图像:

ReLU函数(斜坡函数/修正线性单元)

ReLU函数公式

1
2
3
4
5
6
7
1.优点:
1.1 计算更加高效(采用ReLU的神经元只需要进行加、乘、比较操作)
1.2 具有生物学合理性(单侧抑制、宽兴奋边界) -- 能够保证大约50%的神经元会处于激活状态
1.3 ReLU函数为左饱和函数+x>0时f'(x)=1,在一定程度上缓解了神经网络的梯度消失问题,加速梯度下降的收敛速度
2.缺点:
2.1 输出是非零中心化的,给后一层的神经网络引入偏置偏移,会影响梯度下降的速度
2.2 死亡ReLU问题:ReLU神经元在训练时比较容易"死亡"(如果有一次不恰当的更新后,第一个隐藏层中的某个ReLU神经元在所有训练数据上都不能被激活,在以后的训练过程中永远不能被激活)

带泄露的ReLU

带参数的ReLU

ELU函数

Softplus函数

四种函数图对比:

Swish函数

1
2
1.自门控激活函数
2.通过设置得到1/0 --> 门的状态为"开"/"关"

GELU函数

1
2
1.高斯误差线性单元 --> 通过门控机制来调整其输出值的激活函数
2.特殊的Swish函数

Maxout单元

网络结构

三种网络结构:

前馈神经网络

反向传播算法

##

机器学习实战之工业蒸汽

题目基本情况

数据集

1
2
1.数据集:
https://tianchi.aliyun.com/dataset/dataDetail?dataId=130516

数据探索

理论知识

赛题数据探索

导入工具包

1
2
3
4
5
6
7
8
9
10
11
12

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
from scipy import stats
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

可视化数据分布

箱型图(boxplot)

1
2
3
4
5
6
##2.1 箱型图boxplot(所有特征变量)
columns=train_data.columns.tolist()[:39] #前39列
fig=plt.figure(figsize=(20,40)) #指定绘图对象宽度和高度
for i in range(38):
plt.subplot(8,5,i+1) #指定8行5列子图
sns.boxplot(train_data[columns[i]],orient="h",width=0.5) #orient是v(垂直)/h(水平)

整体的箱型图:

V0一个的箱型图:

直方图(distplot)和Q-Q图(probplot)

1
2
3
4
5
6
7
8
9
10
11
12
##2.3 直方图distplot和Q-Q图probplot(数据的分位数和正态分布的分位数对比参照) -- 如果数据符合正态分布 会在qq图内两条线重合
train_cols=6 #列
train_rows=len(train_data.columns) #行
plt.figure(figsize=(train_cols,train_rows)) #指定绘图对象宽度和高度
i=0
for col in train_data.columns:
i+=1
ax=plt.subplot(train_rows,train_cols,i) #指定r行c列子图第i个位置
sns.distplot(train_data[col],fit=stats.norm) #fit设置函数图像(与原图进行比较)
i+=1
ax=plt.subplot(train_rows,train_cols,i) # 指定r行c列子图第i+1个位置
res=stats.probplot(train_data[col],plot=plt) # fit设置函数图像(与原图进行比较)

KDE分布图(核密度估计kdeplot)

1
2
3
4
5
6
7
8
9
10
11
12
13
##2.4 KDE分布图kdeplot(核密度估计) --对直方图的加窗平滑(可以查看对比训练集和测试集中特征变量的分布情况)
dist_cols=6 #列
dist_rows=len(test_data.columns) #行
plt.figure(figsize=(train_cols,train_rows)) #指定绘图对象宽度和高度
i=1
for col in test_data.columns:
ax=plt.subplot(dist_rows,dist_cols,i) #指定r行c列子图第i个位置
ax=sns.kdeplot(train_data[col],color="Red",shade=True)
ax=sns.kdeplot(test_data[col], color="Blue", shade=True)
ax.set_xlabel(col) #横坐标名称
ax.set_ylabel("Frequency") #纵坐标名称
ax=ax.legend(["训练集","测试集"]) #两条曲线的名称
i=i+1

线性回归关系图(regplot)

1
2
3
4
5
6
7
8
9
10
11
12
##2.5 线性回归关系图regplot(分析变量之间的线性回归关系)
fcols=6 #列
frows=len(test_data.columns) #行
plt.figure(figsize=(fcols,frows)) #指定绘图对象宽度和高度
i=0
for col in test_data.columns:
i=i+1
ax=plt.subplot(frows,fcols,i) #指定r行c列子图第i个位置
sns.regplot(x=col,y='target',data=train_data,ax=ax,scatter_kws={'marker':'.','s':3,'alpha':0.3},line_kws={'color':'k'})
plt.xlabel(col)
plt.ylabel('target')
plt.show()

查看特征变量的相关性

计算相关性系数(data.corr)

1
2
3
4
5
6
7
#3.查看特征变量的相关性
##3.1 计算相关性系数corr --> KDE图中拿训练集和测试集中分布不一致的特征变量进行删除(V5,V9,V11,V17,V22,V28) --> 计算剩余特征变量和target变量的相关性系数
pd.set_option('display.max_columns',10) #显示10列 默认none就是最多
pd.set_option('display.max_rows',10) #显示10行
data_train1=train_data.drop(['V5','V9','V11','V17','V22','V28'],axis=1) #删除那些测试集和训练集分布不一致的特征向量
train_corr=data_train1.corr() #corr给出任意两个变量之间的相关系数
print(train_corr)

相关热力图(sns.heatmap)

1
2
3
##3.2 热力图heatmap
ax=plt.subplots(figsize=(20,16)) #调整画布大小
ax=sns.heatmap(train_corr,vmax=.8,square=True,annot=True) #vmax和vmin是图例中最大值和最小值的显示值 square为热力图矩阵小块形状(T以列名为标签名) annot为T表示每个方格写入数据

根据相关系数筛选特征变量(相关性选择/树模型)

1
2
3
4
5
6
7
8
###3.3.1 寻找k个与target变量最相关的特征变量(K=10)
columns=train_corr.nlargest(10,'target') #利用相关系数.nlargest()获取
columnsindex=columns['target'].index # 获取符合的下标'V0'/'V1'/'V8'/'V27'/'V31'/'V2'/'V4'/'V12'/'V16'
columnsvalue=train_data[columnsindex].values #找到k个特征变量在训练集中的值
cm=np.corrcoef(columnsvalue) #皮尔逊积矩相关系数--计算两个变量x和y之间的线性相关(-1到1)
ax=plt.subplots(figsize=(10,10)) #调整画布大小
ax=sns.heatmap(train_data[columnsindex].corr(),annot=True,square=True) #k个相关值画热力图
plt.show()

1
2
3
4
5
6
###3.3.2 找出与target变量的相关系数大于0.5的特征变量
corrs=train_data.corr() #获取训练数据集的相关系数
corrres=corrs.index[abs(corrs['target'])>0.5] # 获取符合的下标 V0'/'V1'/'V2'/'V3'/'V4'/'V8'/'V12'/'V16'/'V27'/'V31'/'V37'
ax=plt.figure(figsize=(10,10))
ax=sns.heatmap(train_data[corrres].corr(),annot=True,cmap="RdYlGn") #cmap设置颜色
plt.show()

Box-Cox变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
###3.3.3 Box-Cox变换(线性回归基于正态分布 --> 统计分析将数据转换为符合正态分布)
####1. 合并数据
drop_columns = ['V5','V9','V11','V17','V22','V28'] #KDE图发现训练集和测试集中这几个特征变量不一致 需要删除
train_droptarget=train_data.drop(['target'],axis=1) #按照axis=1列删除了target的行和列(因为train里面比test多了target列)
data_all=pd.concat([train_droptarget,test_data]) #默认纵向拼接train和test两个训练集(列不变 行数会变多)
data_all.drop(drop_columns,axis=1,inplace=True) #按照axis=1列删除那些列
####2. 归一化(1.MinMaxScaler函数/2.min-max离差标准化)
colunms_list=list(data_all.columns) #对合并后的每列数据合成一个list列表
def scale_minmax(col): #定义一个标准化的函数用于apply方法的第一个参数
return (col-col.min())/(col.max()-col.min())
data_all[colunms_list]=data_all[colunms_list].apply(scale_minmax,axis=0) # axis=0对每一列数据应用函数

####3. Box-Cox变换
data_all, lambda0 = boxcox1p(data_all)

####4. 重新画Q-Q图
data_all_cols=6 #列
data_all_rows=len(data_all.columns) #行
plt.figure(figsize=(data_all_cols,data_all_rows)) #指定绘图对象宽度和高度
i=0
for col in data_all.columns:
i+=1
ax=plt.subplot(data_all_rows,data_all_cols,i) #指定r行c列子图第i个位置
sns.distplot(data_all[col],fit=stats.norm) #fit设置函数图像(与原图进行比较)
i+=1
ax=plt.subplot(data_all_rows,data_all_cols,i) # 指定r行c列子图第i+1个位置
res=stats.probplot(data_all[col],plot=plt) # fit设置函数图像(与原图进行比较)
plt.show()

特征工程

特征工程的重要性和处理

特征工程的重要性:

1
2
3
4
5
6
 1.特征工程处理流程:
1.1 去掉无用特征
1.2 去掉冗余特征(如共线特征)
1.3 生成新特征(利用存在的特征、转换特征、内容中的特征、其他数据源)
1.4 特征转换(数值化、类别转换、归一化等)
1.5 特征处理(异常值、最大值、最小值、缺失值)

数据预处理和特征处理

数据预处理(数据采集+数据清洗+数据采样)

数据采集

数据清洗

数据采样

1
2
3
4
5
6
7
1.数据采样的原因:经过采集和清洗之后正负样本是不均衡的 --> 数据采样
2.数据采样的方法:
2.1 随机采样: 可能随机采样得到的数据很不均匀
2.2 分层采样:
3.正负样本不均衡的处理办法:
3.1 正样本>负样本 + 量特别大 : 下采样(downsampling)的方法
3.2 正样本>负样本 + 量不大 : 上采样(oversampling)的方法(图像识别的镜像和旋转/修改损失函数设置样本权重)

特征处理

特征处理小结:

标准化(StandardScaler类)

1
2
3
1.标准化: 依照特征矩阵的列去处理数据[通过求标准分数的方法将特征-->标准正态分布]
2.使用场景:
2.1 数据存在异常值和较多噪声

区间缩放法(MinMaxScaler类)

1
1.区间缩放法: 利用两个最值(最大值和最小值)进行缩放 [归一化的一种]

归一化(Normalizer类)

公式:

1
2
3
4
1.归一化: 样本的特征值-->同一量纲,数据-->[0,1]/[a,b]区间内
2.使用场景:
2.1 输出结果范围有要求
2.2 数据较为稳定,不存在极端的最大值/最小值

定量特征二值化(Binarizer类)

公式:

1
1. 定量特征二值化: 核心在于设定一个阈值(>阈值的赋值为1,≤阈值的赋值为0)

定性特征哑编码(OneHotEncoder类)

1
2
3
4
5
6
1.哑变量/虚拟变量(Dummy Variable):通常是认为虚设的变量(0/1),用来反映某个变量的不同属性。
2.哑变量目的: 原本不能定量处理的变量进行量化,从而评估定性因素对因变量的影响
2.1 例如: 变量"职业"取值分别为工人、农民、学生、企业职员、其他(5种选项) --> 工人定义为(0,0,0,1) 那么农民就是(0,0,1,0) 学生就是(0,1,0,0) 企业职工就是(1,0,0,0)

2.哑编码: 类别变量 --> 哑变量
3.哑编码规则:对于有n个类别属性的变量,通常以1个类别特征为参照,产生n-1个哑变量

缺失值处理(impute库的SimpleImputer类)

1
2
1.用Pandas读取后特征均为NaN(数据缺失)
2.使用impute库的SimpleImputer类

数据转换

1
2
3
1.基于多项式的多项式转换(PolynomialFeatures类):参数degree为度(默认值为2)
2.基于对数函数的对数变换:基于单变元函数的数据转换可以使用统一的方法完成(FunctionTransformer类)
3.基于指数函数:

特征降维

特征选择

特征选择三类方法:

1
2
3
4
5
1.特征选择概念:比较简单粗暴,就是映射函数直接将不重要的特征(×),不过会造成特征信息的丢失,不利用模型精度
2.特征选择方法:
2.1 过滤法(Filter):按照发散性/相关性对各个特征进行评分,通过设定阈值/待选择阈值的个数来选择特征
2.2 包装法(Wrapper):按照目标函数(AUC/MSE)每次选择/排除若干特征
2.3 嵌入法(Embedded):使用某些算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征

线性降维

赛题特征工程

异常值分析(箱线图找出异常删除异常)

1
2
3
4
5
6
7
8
9
10
##箱型图
plt.figure(figsize=(18,10))
plt.boxplot(x=train_data.values,labels=train_data.columns) #标签就是训练集的各个列
plt.hlines([-7.5,7.5],0,40,colors='r') #从-7.5到7.5绘制水平线 0和40就是这条线从第几个Vx开始画到第Vx个特征
plt.show()
##删除异常值(通过箱型图可以查看到明显的异常值【比如V9变量】)
train_data=train_data[train_data['V9']>-7.5]
test_data=test_data[test_data['V9']>-7.5]
print(train_data.describe())
print(test_data.describe())

归一化(最大值和最小值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
##归一化(最大值和最小值)  --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

print(train_data_scaler.describe())
print(test_data_scaler.describe())

查看数据分布(KDE差异较大删除特征)

1
2
3
4
5
6
7
8
9
10
11
12
##查看数据分布  --通过KDE分布对比了特征变量在两个数据集中的分布情况(V5/V9/V11/V17/V22/V28在训练集和测试集分布差异较大,会影响模型的泛化能力,故删除这些特征)
drop_col=6 #6列
drop_row=1 #1行
plt.figure(figsize=(5*drop_col,5*drop_row))
for i,col in enumerate(["V5","V9","V11","V17","V22","V28"]): #enumerate函数用于将一个可遍历的数据对象
ax=plt.subplot(1,6,i+1)
ax=sns.kdeplot(train_data_scaler[col],color="Red",shade=True) #画KDE图
ax=sns.kdeplot(test_data_scaler[col],color="Blue",shade=True) #画KDE图
ax.set_xlabel(col) #设置x标签为col
ax.set_ylabel("Frequency") #设置y标签为Frequency
ax=ax.legend(["train", "test"]) #设置两条曲线分别叫train和test
plt.show()

特征相关性(用热力图可视化)

1
2
3
4
5
6
7
8
9
10
##特征相关性(热力图可视化显示)
plt.figure(figsize=(20,16))
column=train_data_scaler.columns.tolist() # 整出来一个列表list表示从V0-V39-target
mcorr=train_data_scaler[column].corr(method="spearman") # spearman表示非线性的 pearson表示相关系数 kendall反映分类变量相关性的指标(无序序列的相关系数)
# zeros_like()函数: 创建一个和mcorr同维度的数组(初始化全为False)
mask=np.zeros_like(mcorr,dtype=np.bool)
# triu_indices_from()函数: 返回矩阵的上三角(上三角全为True)
mask[np.triu_indices_from(mask)]=True
g=sns.heatmap(mcorr,mask=mask,square=True,annot=True,fmt='0.2f') # square为热力图矩阵小块形状(T以列名为标签名) annot为True表示每个方格写入数据 fmt表示小数点后两位
plt.show()

特征降维

1
2
3
4
##特征降维(特征相关性的初筛--计算相关性系数并筛选>0.1的特征变量)
mcorr=mcorr.abs() #将所有取绝对值
numberical_corr=mcorr[mcorr['target']>0.1]['target']
print(numberical_corr.sort_values(ascending=False)) # VX和系数值 (按照系数值进行排序)

多重共线性分析(statsmodels.stats.outliers_influence.variance_inflation_factor)

1
2
3
4
5
6
##多重共线性分析(特征组之间的相关性系数较大) -- 每个特征变量与其他特征变量之间的相关性系数较大所以存在较大的共线性影响 --> 使用PCA进行处理(去除多重共线性)
###statsmodels.stats.outliers_influence.variance_inflation_factor 多重共线性方差膨胀因子
new_numberical=['V0', 'V2', 'V3', 'V4', 'V5', 'V6', 'V10','V11', 'V13', 'V15', 'V16', 'V18', 'V19', 'V20', 'V22','V24','V30', 'V31', 'V37']
X=np.matrix(train_data_scaler[new_numberical]) #根据new_numberical来构成一个二维数组
VIF_list=[variance_inflation_factor(X,i) for i in range(X.shape[1])] # 获得多重共线性方差膨胀因子
print(VIF_list)

PCA处理(去除数据的多重共线性,并进行降维)

1
2
3
4
5
6
7
8
9
10
11
12
13
##PCA处理
### sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=0.9) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_90=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_90=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_90=pd.DataFrame(new_train_pca_90)
new_test_pca_90=pd.DataFrame(new_test_pca_90)
new_train_pca_90['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分
print(new_train_pca_90.describe())
print("----------------------------------------------")
print(train_data_scaler.describe())

模型训练

回归和相关模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from scipy import stats
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #评价指标
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段


#3.归一化(最大值和最小值) --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

#3.PCA处理
### 1.sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=0.9) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_90=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_90=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_90=pd.DataFrame(new_train_pca_90)
new_test_pca_90=pd.DataFrame(new_test_pca_90)
new_train_pca_90['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分
### 2.sklearn.decomposition.PCA PCA处理之后可保持95%的信息数据
pca = PCA(n_components=0.95)
#获得转换器
new_train_pca_16 = pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_16 = pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_16 = pd.DataFrame(new_train_pca_16)
new_test_pca_16 = pd.DataFrame(new_test_pca_16)
new_train_pca_16['target'] = train_data_scaler['target'] # PCA处理之后保留了16个主成分

#2.切分数据(训练集--> 80%训练集和20%验证数据)
new_train_pca_16=new_train_pca_16.fillna(0) #采用PCA保留16维特征的数据
train=new_train_pca_16[new_test_pca_16.columns]
target=new_train_pca_16['target']
##切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)

#4.线性回归
clf=LinearRegression() #实例化
clf.fit(train_data,train_target) #创建训练集的转换器
test_pred=clf.predict(test_data) #获得测试集的预测
score=mean_squared_error(test_target,test_pred) #判断测试集的目标值和测试集的预测值
print("线性回归预测结果:",score) # 结果为0.13468236081062834

#5.K近邻
clf=KNeighborsRegressor(n_neighbors=3) # k取3
clf.fit(train_data,train_target)
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("K近邻回归预测结果:",score) # 结果为0.22391053287197232

#6.决策树回归
clf=DecisionTreeRegressor()
clf.fit(train_data,train_target)
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("决策树回归预测结果:",score) # 结果为0.33070805190311414

#7.随机森林回归
clf=RandomForestRegressor(n_estimators=200) #创建200课树的模型
clf.fit(train_data,train_target)
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("随机森林回归预测结果:",score) # 结果为

#8.LightGBM回归(微软开发的一个GBDT算法框架--更快的训练速度,更低的内存消耗,更好的准确率,处理海量数据)
##(1)连续的浮点特征值 --> k个整数 + (2)构造一个宽度为k的直方图 [遍历时,将离散化后的值作为索引在直方图中积累统计量]

赛题模型训练

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from scipy import stats
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #评价指标
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

#3归一化(最大值和最小值) --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

#3.PCA处理
### 1.sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=0.9) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_90=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_90=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_90=pd.DataFrame(new_train_pca_90)
new_test_pca_90=pd.DataFrame(new_test_pca_90)
new_train_pca_90['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分
### 2.sklearn.decomposition.PCA PCA处理之后可保持95%的信息数据
pca = PCA(n_components=0.95)
#获得转换器
new_train_pca_16 = pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_16 = pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_16 = pd.DataFrame(new_train_pca_16)
new_test_pca_16 = pd.DataFrame(new_test_pca_16)
new_train_pca_16['target'] = train_data_scaler['target'] # PCA处理之后保留了16个主成分

#2.切分数据(训练集--> 80%训练集和20%验证数据)
new_train_pca_16=new_train_pca_16.fillna(0) #采用PCA保留16维特征的数据
train=new_train_pca_16[new_test_pca_16.columns]
target=new_train_pca_16['target']
##切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)

#4.线性回归(效果一般,适合分析使用)
clf=LinearRegression() #实例化
clf.fit(train_data,train_target) #创建训练集的转换器
test_pred=clf.predict(test_data) #获得测试集的预测
score=mean_squared_error(test_target,test_pred) #判断测试集的目标值和测试集的预测值
print("线性回归预测结果:",score) # 结果为0.13468236081062834

#5.K近邻(效果一般)
clf=KNeighborsRegressor(n_neighbors=8) # k取8 最近8个
clf.fit(train_data,train_target)
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("K近邻回归预测结果:",score) # 结果为0.22391053287197232

#6.决策树回归
clf=DecisionTreeRegressor()
clf.fit(train_data,train_target)
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("决策树回归预测结果:",score) # 结果为0.33070805190311414

#7.随机森林回归(比较合适)
clf=RandomForestRegressor(n_estimators=200) #创建200课树的模型
clf.fit(train_data,train_target)
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("随机森林回归预测结果:",score) # 结果为

#8.LightGBM回归(微软开发的一个GBDT算法框架--更快的训练速度,更低的内存消耗,更好的准确率,处理海量数据)
##(1)连续的浮点特征值 --> k个整数 + (2)构造一个宽度为k的直方图 [遍历时,将离散化后的值作为索引在直方图中积累统计量]
clf=lgb.LGBMRegressor(
learning_rate=0.01, # 学习率 推荐的候选值为:[0.01, 0.015, 0.025, 0.05, 0.1]
max_depth=-1, # 指定树的最大深度(防止过拟合)
n_estimators=5000, # 树的数量
boosting_type='gbdt', # 指定弱学习器的类型 -- gbdt表示使用基于树的模型进行计算(默认)/gblinear表示使用线性模型/rf使用随机森林
random_state=2019,
objective='regression' # regression是使用L2正则项的回归模型(默认) /regression_l1是使用L1正则项的回归模型 /mape平均绝对百分比误差 /binary二分类 /multiclass多分类
)
##训练模型
clf.fit(X=train_data,y=train_target,eval_metric='MSE') #eval_metric表示评价指标(默认是logloss) MSE是均方误差
test_pred=clf.predict(test_data)
score=mean_squared_error(test_target,test_pred)
print("lightGbm回归预测结果:",score)

模型验证

模型评估的概念和方法

欠拟合和过拟合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from scipy import stats
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #评价指标
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

#生成数据集并可视化显示
np.random.seed(666) #随机生成666个种子
x=np.random.uniform(-3.0,3.0,size=100) #随机数的最小值是-3.0 最大值是3.0
X=x.reshape(-1,1) #reshape更改数据的行列数目
y=0.5*x**2+x+2+np.random.normal(0,1,size=100)
plt.scatter(x,y) #生成散点图
plt.show()

#1.使用线性回归模型对数据进行拟合
lin_reg=LinearRegression()
lin_reg.fit(X,y)
print("准确率为:",lin_reg.score(X,y)) #准确率约为0.495(比较低) --可见直线拟合数据的程度较低
##使用均方误差来评价拟合程度
y_predict=lin_reg.predict(X)
print("均方误差为:",mean_squared_error(y,y_predict)) # 均方误差为3.0750025765636577
##绘制拟合结果
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict[np.argsort(x)],color='r')
plt.show()

#2.使用多项式回归拟合(2.1封装Pipeline管道 2.2使用Pipeline拟合数据,多项式参数设置为degree=x)
##2.1 封装Pipeline管道(以便于下一步灵活调整多项式回归模型参数)
def PolynomialRegression(degree):
return Pipeline(
[('poly',PolynomialFeatures(degree=degree)),
('std_scaler',StandardScaler()),
('lin_reg',LinearRegression())])

##2.2使用Pipeline拟合数据(多项式参数设置为degree=2)
poly2_reg=PolynomialRegression(degree=2) #使用degree=2
poly2_reg.fit(X,y)
y2_predict=poly2_reg.predict(X)
print("degree为2时候的均方误差为:",mean_squared_error(y,y2_predict)) # 均方误差为1.0987392142417858
##绘制拟合结果
plt.scatter(x,y)
plt.plot(np.sort(x),y2_predict[np.argsort(x)],color='r')
plt.show()

##2.2使用Pipeline拟合数据(多项式参数设置为degree=10)
poly10_reg=PolynomialRegression(degree=10) #使用degree=10
poly10_reg.fit(X,y)
y10_predict=poly10_reg.predict(X)
print("degree为10时候的均方误差为:",mean_squared_error(y,y10_predict)) # 均方误差为1.050846676376416
##绘制拟合结果
plt.scatter(x,y)
plt.plot(np.sort(x),y10_predict[np.argsort(x)],color='r')
plt.show()

##2.3使用Pipeline拟合数据(多项式参数设置为degree=100)
poly100_reg=PolynomialRegression(degree=100) #使用degree=100
poly100_reg.fit(X,y)
y100_predict=poly100_reg.predict(X)
print("degree为100时候的均方误差为:",mean_squared_error(y,y100_predict)) # 均方误差为0.6831833931625624
##绘制拟合结果
plt.scatter(x,y)
plt.plot(np.sort(x),y100_predict[np.argsort(x)],color='r')
plt.show()

模型的泛化与正则化

回归模型的评估指标和调用方法

四种回归模型评估方法:

四种回归模型评估的公式:

交叉验证

1.简单交叉验证

2.K折交叉验证

3.留一法交叉验证

4.留P法交叉验证

5.其他交叉验证

模型调参

调参的概念

1
2
3
4
5
 1.参数分类:
1.1 过程影响类参数: 子模型不变的前提下,调整"子模型数(n_estimators)和学习率(learning_rate)" --> 改变训练过程,提高整体模型的性能
1.2 子模型影响类参数: 调整"最大树深度(max_depth)和分裂条件(criterion)" --> 改变子模型的性能,提高整体模型的性能
1.3 bagging: 降低方差
1.4 boosting: 降低偏差

参数的影响

参数对Random Forest的影响

参数对Gradient Tree Boosting的影响

学习曲线

验证曲线

赛题模型验证和调参

模型过拟合与欠拟合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from scipy import stats
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #均方误差
from sklearn.metrics import mean_absolute_error #平均绝对值误差
from math import sqrt #平方根
from sklearn.metrics import r2_score #R平方值
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import SGDRegressor
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

#2.归一化(最大值和最小值) --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

#3.PCA处理
### 1.sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=16) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_16=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_16=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_16=pd.DataFrame(new_train_pca_16)
new_test_pca_16=pd.DataFrame(new_test_pca_16)
new_train_pca_16['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分

#4.切分数据(训练集--> 80%训练集和20%验证数据)
new_train_pca_16=new_train_pca_16.fillna(0) #采用PCA保留16维特征的数据
train=new_train_pca_16[new_test_pca_16.columns]
target=new_train_pca_16['target']
##切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)

#5.欠拟合(没有多项式转换)
clf=SGDRegressor(max_iter=500,tol=1e-2) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data,train_target)
score_train=mean_squared_error(train_target,clf.predict(train_data)) # 训练集的均方误差
score_test=mean_squared_error(test_target,clf.predict(test_data)) # 测试集的均方误差
print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE:0.14152723650374396
print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE:0.1470304756084494

#6.过拟合(多项式转换系数过大)
poly=PolynomialFeatures(5) #多项式转换 写5
train_data_poly=poly.fit_transform(train_data)
test_data_poly=poly.transform(test_data)
clf=SGDRegressor(max_iter=1000,tol=1e-3) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data_poly, train_target) #装在转换器
score_train = mean_squared_error(train_target, clf.predict(train_data_poly))
score_test = mean_squared_error(test_target, clf.predict(test_data_poly))
print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE: 0.1332651075687169
print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE: 0.14544120121194679

#7.正常拟合
poly=PolynomialFeatures(3) #多项式转换 写3
train_data_poly=poly.fit_transform(train_data)
test_data_poly=poly.transform(test_data)
clf=SGDRegressor(max_iter=1000,tol=1e-3) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data_poly, train_target) #装在转换器
score_train = mean_squared_error(train_target, clf.predict(train_data_poly))
score_test = mean_squared_error(test_target, clf.predict(test_data_poly))
print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE: 0.13343001175858962
print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE: 0.14179907981584394

模型正则化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from scipy import stats
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #均方误差
from sklearn.metrics import mean_absolute_error #平均绝对值误差
from math import sqrt #平方根
from sklearn.metrics import r2_score #R平方值
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import SGDRegressor
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段


#2.归一化(最大值和最小值) --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

#3.PCA处理
### 1.sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=16) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_16=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_16=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_16=pd.DataFrame(new_train_pca_16)
new_test_pca_16=pd.DataFrame(new_test_pca_16)
new_train_pca_16['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分

#4.切分数据(训练集--> 80%训练集和20%验证数据)
new_train_pca_16=new_train_pca_16.fillna(0) #采用PCA保留16维特征的数据
train=new_train_pca_16[new_test_pca_16.columns]
target=new_train_pca_16['target']
##切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)

#8.模型正则化
##8.1 L2范数正则化
poly=PolynomialFeatures(3) #多项式转换 写3
train_data_poly=poly.fit_transform(train_data)
test_data_poly=poly.transform(test_data)
clf=SGDRegressor(max_iter=1000,tol=1e-3,penalty='L2',alpha=0.0001) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data_poly, train_target) #装在转换器
score_train = mean_squared_error(train_target, clf.predict(train_data_poly))
score_test = mean_squared_error(test_target, clf.predict(test_data_poly))
print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE: 0.13343001175858962
print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE: 0.14179907981584394

##8.2 L1范数正则化
poly=PolynomialFeatures(3) #多项式转换 写3
train_data_poly=poly.fit_transform(train_data)
test_data_poly=poly.transform(test_data)
clf=SGDRegressor(max_iter=1000,tol=1e-3,penalty='L1',alpha=0.0001) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data_poly, train_target) #装在转换器
score_train = mean_squared_error(train_target, clf.predict(train_data_poly))
score_test = mean_squared_error(test_target, clf.predict(test_data_poly))
print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE: 0.1347595438689653
print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE: 0.14295179346699013

##8.3 ElasticNet联合L1和L2范数加权正则化
poly=PolynomialFeatures(3) #多项式转换 写3
train_data_poly=poly.fit_transform(train_data)
test_data_poly=poly.transform(test_data)
clf=SGDRegressor(max_iter=1000,tol=1e-3,penalty='elasticnet',l1_ratio=0.9,alpha=0.0001) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data_poly, train_target) #装在转换器
score_train = mean_squared_error(train_target, clf.predict(train_data_poly))
score_test = mean_squared_error(test_target, clf.predict(test_data_poly))
print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE: 0.13501686392085374
print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE: 0.14315710816572816

模型交叉验证(四种)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler #归一化
from scipy import stats
from sklearn.decomposition import PCA #PCA主成分降维
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #均方误差
from sklearn.metrics import mean_absolute_error #平均绝对值误差
from math import sqrt #平方根
from sklearn.metrics import r2_score #R平方值
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline #管道
from sklearn.preprocessing import PolynomialFeatures #多项式转变
from sklearn.preprocessing import StandardScaler #标准化
from sklearn.linear_model import SGDRegressor #随机递推下降
from sklearn.model_selection import KFold #KFold是K折交叉验证
from sklearn.model_selection import LeaveOneOut #留一法
from sklearn.model_selection import LeavePOut #留P法
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

#2.归一化(最大值和最小值) --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

#3.PCA处理
### 1.sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=16) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_16=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_16=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_16=pd.DataFrame(new_train_pca_16)
new_test_pca_16=pd.DataFrame(new_test_pca_16)
new_train_pca_16['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分

#4.切分数据(训练集--> 80%训练集和20%验证数据)
new_train_pca_16=new_train_pca_16.fillna(0) #采用PCA保留16维特征的数据
train=new_train_pca_16[new_test_pca_16.columns]
target=new_train_pca_16['target']
##切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)

#5.模型交叉验证
##5.1 简单交叉验证
clf=SGDRegressor(max_iter=1000,tol=1e-3) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data,train_target) #装在转换器
score_train = mean_squared_error(train_target, clf.predict(train_data))
score_test = mean_squared_error(test_target, clf.predict(test_data))
#print("SGDRegressor train MSE:",score_train) # SGDRegressor train MSE: 0.1415415271798254
#print("SGDRegressor test MSE:",score_test) # SGDRegressor test MSE: 0.147046507243961

##5.2 k折交叉验证
kf=KFold(n_splits=5)
for k,(train_index,test_index) in enumerate(kf.split(train)):
train_data,test_data,train_target,test_target=train.values[train_index],train.values[test_index],target[train_index],target[test_index]
clf = SGDRegressor(max_iter=1000,tol=1e-3) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data,train_target)
score_train = mean_squared_error(train_target, clf.predict(train_data))
score_test = mean_squared_error(test_target, clf.predict(test_data))
print(k,"折","SGDRegressor train MSE:",score_train) # x 折 SGDRegressor train MSE: 0.1415415271798254
print(k,"折","SGDRegressor test MSE:",score_test) # x 折 SGDRegressor train MSE: 0.1415415271798254

##5.3 留一法 LOO CV
loo=LeaveOneOut()
num=100
for k,(train_index,test_index) in enumerate(loo.split(train)):
train_data,test_data,train_target,test_target = train.values[train_index],train.values[test_index],target[train_index],target[test_index]
clf = SGDRegressor(max_iter=1000,tol=1e-3) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data,train_target)
score_train = mean_squared_error(train_target, clf.predict(train_data))
score_test = mean_squared_error(test_target, clf.predict(test_data))
print(k,"个","SGDRegressor train MSE:",score_train)
print(k,"个","SGDRegressor test MSE:",score_test)
if k >= 9:
break

##5.4 留P法 LPO CV
lpo=LeavePOut(p=10)
num=100
for k,(train_index, test_index) in enumerate(lpo.split(train)):
train_data,test_data,train_target,test_target = train.values[train_index],train.values[test_index],target[train_index],target[test_index]
clf = SGDRegressor(max_iter=1000,tol=1e-3) # max_iter表示是训练数据的最大传递次数 tol是停止标准
clf.fit(train_data, train_target)
score_train = mean_squared_error(train_target, clf.predict(train_data))
score_test = mean_squared_error(test_target, clf.predict(test_data))
print(k,"10个","SGDRegressor train MSE:",score_train)
print(k,"10个","SGDRegressor test MSE:",score_test)
if k >= 9:
break

模型超参空间及调参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler #归一化
from scipy import stats
from sklearn.decomposition import PCA #PCA主成分降维
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #均方误差
from sklearn.metrics import mean_absolute_error #平均绝对值误差
from math import sqrt #平方根
from sklearn.metrics import r2_score #R平方值
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline #管道
from sklearn.preprocessing import PolynomialFeatures #多项式转变
from sklearn.preprocessing import StandardScaler #标准化
from sklearn.linear_model import SGDRegressor #随机递推下降
from sklearn.model_selection import KFold #KFold是K折交叉验证
from sklearn.model_selection import LeaveOneOut #留一法
from sklearn.model_selection import LeavePOut #留P法
from sklearn.model_selection import GridSearchCV #网格搜索
from sklearn.model_selection import RandomizedSearchCV
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

#2.归一化(最大值和最小值) --放缩到(0,1区间)
features_columns=[col for col in train_data.columns if col not in ['target']] #从V0到V37
min_max_scaler=preprocessing.MinMaxScaler().fit(train_data[features_columns])

train_data_scaler=min_max_scaler.transform(train_data[features_columns])
test_data_scaler=min_max_scaler.transform(test_data[features_columns])

train_data_scaler=pd.DataFrame(train_data_scaler) #将训练集数据弄成DF格式
train_data_scaler.columns=features_columns

test_data_scaler=pd.DataFrame(test_data_scaler) #将测试集数据弄成DF格式
test_data_scaler.columns=features_columns

train_data_scaler['target'] = train_data['target']

#3.PCA处理
### 1.sklearn.decomposition.PCA PCA处理之后可保持90%的信息数据
pca=PCA(n_components=16) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
new_train_pca_16=pca.fit_transform(train_data_scaler.iloc[:,0:-1])
new_test_pca_16=pca.transform(test_data_scaler)
#转移为DF格式
new_train_pca_16=pd.DataFrame(new_train_pca_16)
new_test_pca_16=pd.DataFrame(new_test_pca_16)
new_train_pca_16['target']=train_data_scaler['target'] # PCA处理之后保留了16个主成分

#4.切分数据(训练集--> 80%训练集和20%验证数据)
new_train_pca_16=new_train_pca_16.fillna(0) #采用PCA保留16维特征的数据
train=new_train_pca_16[new_test_pca_16.columns]
target=new_train_pca_16['target']
##切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)

#5.模型超参空间及调参
##5.1 穷举网格搜索
randomForestRegressor=RandomForestRegressor()
parameters={
'n_estimators':[50,100,200], #预测器数量
'max_depth':[1,2,3] #最大深度
}
clf=GridSearchCV(randomForestRegressor,parameters,cv=5) # cv指定几折交叉验证(训练集中训练集和验证集的划分有几次,然后得出平均值)
clf.fit(train_data,train_target)
score_test = mean_squared_error(test_target, clf.predict(test_data)) #均方误差
print("RandomForestRegressor GridSearchCV test MSE:",score_test) # 0.25522816178256824
##5.2 随机参数优化
randomForestRegressor = RandomForestRegressor()
parameters = {
'n_estimators':[50, 100, 200, 300], #预测器数量
'max_depth':[1, 2, 3, 4, 5] #最大深度
}
clf=RandomizedSearchCV(randomForestRegressor,parameters,cv=5)
clf.fit(train_data,train_target)
score_test = mean_squared_error(test_target, clf.predict(test_data)) #均方误差
print("RandomForestRegressor RandomizedSearchCV test MSE:",score_test) #
print(sorted(clf.cv_results_))
##5.3 LGB调参(使用数据训练LGB模型,采用网格搜索方法调参)
clf=lgb.LGBMRegressor(num_leaves=31)
parameters = {
'learning_rate': [0.01, 0.1, 1], #学习率
'n_estimators': [20, 40] #预测器数量
}
clf=GridSearchCV(clf,parameters,cv=5)
clf.fit(train_data,train_target)
print('Best parameters found by grid search are:',clf.best_params_) #最好的学习率和预测器个数
score_test=mean_squared_error(test_target,clf.predict(test_data))
print("LGBMRegressor RandomizedSearchCV test MSE:",score_test) # LGBMRegressor RandomizedSearchCV test MSE: 0.15175110081465454

特征优化

特征优化的方法

赛题特征优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler #归一化
from scipy import stats
from sklearn.decomposition import PCA #PCA主成分降维
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #均方误差
from sklearn.metrics import mean_absolute_error #平均绝对值误差
from math import sqrt #平方根
from sklearn.metrics import r2_score #R平方值
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline #管道
from sklearn.preprocessing import PolynomialFeatures #多项式转变
from sklearn.preprocessing import StandardScaler #标准化
from sklearn.linear_model import SGDRegressor #随机递推下降
from sklearn.model_selection import KFold #KFold是K折交叉验证
from sklearn.model_selection import LeaveOneOut #留一法
from sklearn.model_selection import LeavePOut #留P法
from sklearn.model_selection import GridSearchCV #网格搜索
from sklearn.model_selection import RandomizedSearchCV
#1.读取数据
train_data_file = "zhengqi_train.txt"
test_data_file = "zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') #训练集数据共有2888个样本(V0-V37共38个特征变量) -- 有target字段
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') #测试集数据共有1925个样本(V0-V37共有38个特征变量) -- 无target字段

#2.特征构造方法
epsilon=1e-5
#组合交叉特征(自行定义) --增加x*x/y log(x)/y等
function_dict = {
'add': lambda x,y: x+y, #加法
'mins': lambda x,y: x-y, #减法
'div': lambda x,y: x/(y+epsilon), #除法
'multi': lambda x,y: x*y #乘法
}

#3.特征构造函数
def auto_features_make(train_data,test_data,function_dict,col_list): #传入训练集、测试集、特征构造方法、list集合
train_data,test_data=train_data.copy(),test_data.copy() #获取训练集和测试集
for i in col_list:
for j in col_list:
for function_name,function in function_dict.items(): #获取四个函数的函数名和函数
for data in [train_data,test_data]: #从训练集和测试集获取数据
function_features=function(data[i],data[j]) # data[i]就是x data[j]就是y
col_function_features='-'.join([i,function_name,j])
data[col_function_features]=function_features
return train_data,test_data

#4.特征降维处理 --- 先构造新特征,然后使用PCA方法对特征进行降维处理
train_data2,test_data2=auto_features_make(train_data,test_data,function_dict,col_list=test_data.columns)
pca=PCA(n_components=500) # 整数表示保留几个特征 小数表示百分之多少的信息
#获得转换器
train_data2_pca=pca.fit_transform(train_data2.iloc[:,0:-1])
test_data2_pca=pca.transform(test_data2)
#转移为DF格式
train_data2_pca=pd.DataFrame(train_data2_pca)
test_data2_pca=pd.DataFrame(test_data2_pca)
train_data2_pca['target']=train_data2['target'] # PCA处理之后保留了16个主成分
X_train2=train_data2[test_data2.columns].values
y_train=train_data2['target']

#5.使用LightGBM模型对新构造的特征进行模型训练和评估

模型融合

模型优化

模型学习曲线

1
2
3
1.欠拟合(高偏差): 模型太简单(没能力学习到样本的底层规律) -- 训练集和测试集的准确率很低
2.过拟合(高方差): 模型太复杂(学习太过) -- 训练集准确率较好 测试集的准确率很低(相差较大)
3.正常拟合

模型融合提升技术

1
2
3
4
1.概念:产生一组个体学习器 --根据某种策略 --> 结合个体学习器,加强模型效果
2.分类:
2.1 个体学习器之间不存在(×)强依赖关系 可以同时生成的并行化方法 --> Bagging方法和随机森林
2.2 个体学习器之间存在(√)强依赖关系 必须串行的序列化方法 --> Boosting方法

Bagging方法

1
2
3
4
1.概念:从训练集中抽样得到每个基模型所需要的子训练集 --> 对所有基模型预测的结果进行综合,产生最终的预测结果
2.Bagging方法采用 --> 自助采样法(Bootstrap sampling)
2.1 m个样本的原始训练集,每次先随机采集一个样本放入采样集,然后将该样本放回
2.2 m个样本(随机采样),所以会得到m个样本的采样集(可以得到多个不同的弱学习器)

随机森林

1
2
3
4
5
1.概念:(对Bagging方法改进)
2.改进之处:
2.1 基本学习器限定为决策树
2.2 决策树学习过程中引入了随机属性选择
2.3 对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后从这个子集中选择一个最优属性进行划分(就是划分很多小块然后小块里面选个最优属性划分,然后慢慢更新)

Boosting方法

1
2
3
4
5
6
7
8
1.概念:(阶梯状)基模型按照次序一一进行训练
2.基模型的训练集按照某种策略进行一定的转换 --> 所有基模型预测的结果进行线性综合,产生最终预测结果
3.Boosting方法中著名的算法
3.1 AdaBoost算法 :加法模型、损失函数为指数函数、学习算法为前向分布算法
3.2 提升树(Boosting Tree) : 加法模型、基本学习器为决策树、学习算法为前向分布算法 的二分类算法
3.2.1 对于二分类问题: 损失函数为指数函数
3.2.2 对于回归问题: 损失函数为平方误差
3.3 梯度提升树 : (对提升树算法的改进) 可以将损失函数的负梯度在当前模型的值 <--> 残差的近似值

预测结果融合策略

Stacking示意:

1
2
3
4
5
6
7
8
9
10
11
12
13
1.Voting(投票机制): 采用少数服从多数的原则
1.1 硬投票:对多个模型直接进行投票,投票数最多的类 --> 最终被预测的类
1.2 软投票:不同模型设置不同权重,对多个模型直接进行投票,投票数最多的类 --> 最终被预测的类
2.Averaging:将模型结果的平均值 --> 最终的预测值(不同回归方法预测结果波动幅度相差比较大)
3.Ranking:排名平均的方法(如果有权重,就求出n个模型权重比排名之和)
4.Blending:
4.1 先将原始的训练集分为两个部分(训练集 -> 训练集+测试集)
4.2 在第一层中,用70%的数据训练多个模型,然后去预测剩余30%数据的label
4.3 在第二层中,用30%的数据在第一层预测的结果作为新特征继续训练即可
5.Stacking: 用训练好的所有基模型对训练集进行预测
5.1 第j个基模型对第i个训练样本的预测值作为新的训练集中第i个样本的第j个特征值(最后基于新的训练集进行训练)
5.2 同理,预测的过程也要先经过所有基模型的预测形成新的测试集,最后对测试集进行测试
5.3 Stacking是一种分层模型集成框架 -- 第一层由多个基学习器组成(输入为原始训练集) 第二层由第一层基学习器的输出作为训练集进行训练

最终导包汇总

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler #归一化
from scipy import stats
from sklearn.decomposition import PCA #PCA主成分降维
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR # 支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #均方误差
from sklearn.metrics import mean_absolute_error #平均绝对值误差
from math import sqrt #平方根
from sklearn.metrics import r2_score #R平方值
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
from sklearn.pipeline import Pipeline #管道
from sklearn.preprocessing import PolynomialFeatures #多项式转变
from sklearn.preprocessing import StandardScaler #标准化
from sklearn.linear_model import SGDRegressor #随机递推下降
from sklearn.model_selection import KFold #KFold是K折交叉验证
from sklearn.model_selection import LeaveOneOut #留一法
from sklearn.model_selection import LeavePOut #留P法
from sklearn.model_selection import GridSearchCV #网格搜索
from sklearn.model_selection import RandomizedSearchCV

统计学习方法

机器学习入门策略

参考的路线:

统计学习方法

统计学习

1
2
3
4
5
6
7
8
9
10
11
12
13
1.统计学习:关于计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析的一门学科
2.统计学习分类:
2.1 监督学习
2.2 非监督学习
2.3 半监督学习
2.4 强化学习
3.统计学习方法步骤:
3.1 得到一个有限的训练数据集合
3.2 确定包含所有可能的所有模型(学习模型的集合)
3.3 确定选择模型的标准(学习的策略)
3.4 实现求解最优模型的算法(学习的算法)
3.5 通过学习方法选择最优模型
3.6 利用最优模型对新数据进行预测或分析

监督学习

基本概念

1
2
3
4
5
6
7
8
9
10
11
12
13
1.输入/输出空间: 输入与输出所有可能取值的集合
1.1 可以是有限元素的集合
1.2 可以是整个欧式空间
1.3 可以是同一个空间,也可以是不同空间(输出空间<<输入空间)
2.每个具体的输入是一个实例(instance),是用特征向量表示。[所有特征向量存在的空间被称为特征空间]
3.监督学习类型:
3.1 回归问题:输入变量和输出变量均为连续变量的预测问题
3.2 分类问题:输出变量为有限个离散变量的预测问题
3.3 标注问题:输入变量与输出变量均为变量序列的预测问题
4.联合概率分布(P(X,Y)):
监督学习假设输入与输出的随机变量X和Y遵循联合概率分布P(X,Y)
5.假设空间:
模型输入由输入空间->输出空间的映射的集合

问题的形式化

统计学习三要素(方法=模型+策略+算法)

模型(条件概率分布/决策函数)

1
2


策略

1
2


算法

1
2


模型评估与模型选择

训练误差与测试误差

过拟合与模型选择

正则化与交叉验证

正则化

交叉验证

泛化能力

泛化误差

泛化误差上界

生成模型与判别模型

分类问题

标注问题

回归问题

利用python进行数据分析

Numpy基础(数组和矢量计算)

numpy功能

1
2
3
4
5
6
7
8
9
10
1.高性能科学计算和数据分析的基础包
2.部分功能:
2.1 ndarray:具有矢量算术运算+复杂广播能力的多维数组
2.2 快速运算的标准数学函数
2.3 读写磁盘数据的工具
2.4 操作内存映射文件的工具
2.5 线性代数
2.6 随机数生成
2.7 傅里叶变换功能
2.8 集成代码的工具

多维数组对象(ndarray)

1
2
3
4
1.ndarray是一个通用的同构数据多维容器(所有元素必须是同类型的)
2.每个数组:
一个shape表示各维度大小的元组 (2,3) 就是两行三列
一个dtype用于说明数组数据类型的对象 float64 就是float类型64位

创建ndarray

函数总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import numpy as np
#普通序列
data1=[6,7.5,8,0,1]
arr1=np.array(data1)
print(arr1)
#嵌套序列
data2=[[1,2,3,4],[5,6,7,8]]
arr2=np.array(data2)
print(arr2)
print(f"arr1的维度:{arr1.shape}")
print(f"arr2的维度:{arr2.shape}")
print(f"arr1的数据类型:{arr1.dtype}")
print(f"arr2的数据类型:{arr2.dtype}")

#函数新建数组
##创0
data3=np.zeros(10) #创建10个
data33=np.zeros((3,6)) #创建3行6列
data333=np.empty(10) #多数情况下返回的是未初始化的垃圾值

##创1
data4=np.ones(10) #创建10个

print(data3)
print(data33)
print(data333)
print(data4)

#函数常见n*n的单位矩阵(主对角线为1,其余为0)
data5=np.eye(5)
print(data5)

执行结果

ndarray数据类型

数据类型总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
#创建arr
arr1=np.array([1,2,3],dtype=np.float64) #创建时候给出内容和dtype
arr2=np.array([1,2,3],dtype=np.int32)
print(arr1.dtype)
print(arr2.dtype)

#astype方法显式转换dtype ---> 创建出一个新的数组(原始数据的一份拷贝)
arr1=np.array([1,2,3,4,5])
#int32
print(arr1.dtype)
float_arr=arr1.astype(np.float64)
#float64
print(float_arr.dtype)

执行结果

数组和标量之间的运算

1
2
3
4
5
6
7
8
9
import numpy as np
#创建arr
arr=np.array([[1.,2.,3],[4.,5.,6.]]) 两行列表
print(arr)
print(arr*arr)
print(arr-arr)
#数组与标量的算术运算
print(1/arr)
print(arr**0.5)

执行结果

基本的索引和切片

一维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
#创建arr
arr=np.arange(10)
#输出arr所有元素
print(arr)
#输出第6位元素
print(arr[5])
#输出6-8位元素
print(arr[5:8])
#将6-8位元素值都更改为100
arr[5:8]=100
#重新输出
print(arr)

执行结果

1
2
3
4
5
6
7
8
9
10
import numpy as np
#创建arr
arr=np.arange(10)
print(arr)
arr_slice=arr[5:8] #形成切片
arr_slice[1]=12345 #只改切片的第一个
print(arr)
#切片所有都改
arr_slice[:]=1000
print(arr) #arr也会被改变

执行结果

高维数组

索引列表

1
2
3
4
5
6
7
8
9
10
import numpy as np
#创建arr
arr=np.array([[1,2,3],[4,5,6],[7,8,9]])
#输出原始数组
print(arr)
#第二个 一位数组
print(arr[2])
#索引列表(逗号隔开) --> 单个元素
print(arr[0][2])
print(arr[0,2])

执行结果

切片索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
#创建arr
arr=np.array([[1,2,3],[4,5,6],[7,8,9]])
#输出原始数组
print(arr)

#1.一维对象
arr1=arr[1:3] #输出从1轴到2轴
print(arr1)

#2.多维对象
##2.1一个/多个轴进行切片
arr2=arr[:2] #输出0轴开始到1轴
print(arr2)

arr3=arr[:2,1:] #h横:输出0轴到1轴 竖:输出1轴到最后轴
print(arr3)

执行结果

1
2
3
4
5
6
7
8
import numpy as np
#创建arr
arr=np.array([[1,2,3],[4,5,6],[7,8,9]])
##2.2整数索引混合进行切片
arr4=arr[1,:2] #横:输出1轴 竖:输出0轴到1轴
print(arr4)
arr5=arr[2,:1] #横:输出2轴 竖:输出0轴
print(arr5)

执行结果

布尔型索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
#创建 数组(存储数据)+数组(存储姓名)
names=np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
data=np.random.randn(7,4)
print(names)
print(data)
print(names=='Bob') #数组的比较是矢量化的 ---> 产生一个布尔型数组
#数组索引
print(data[names=='Bob']) #Bob对应的那些数字行
#混合使用
print(data[names=='Bob',2:]) #Bob对应的那些的2轴到最后一轴
#进行否定: 不等于!= 负号-
print(data[names!='Bob'])
print(data[~(names=='Bob')])
#z组合布尔条件 和& 或|
res=(names=='Bob')|(names=='Will') #or和and关键字在布尔型数组会无效
print(data[res])

执行结果

花式索引

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
arr=np.empty((8,4)) #创建一个8行4列的数组
for i in range(8): #每行赋当前行的值
arr[i]=i
print(arr) #输出数组所有元素

#特定顺序选取行子集 ---> 传入一个整数列表/ndarray(指定顺序)
##1.正数 从开头开始
print(arr[[4,3,0,6]]) 输出4 3 0 6 四行
##2.负数 从末尾开始
print(arr[[-3,-5,-7]]) 输出5 3 1 三行

执行结果

数组转置和轴对称

reshape函数

1
2
3
4
5
6
7
import numpy as np
arr=np.arange(32).reshape((8,4))
print(arr)
#选取下标(1,0),(5,3),(7,1),(2,2)
print(arr[[1,5,7,2],[0,3,1,2]])
#使用n.p.ix_函数 将两个一维整数数组->用于选取方形区域的索引器
print(arr[np.ix_([1,5,7,2],[0,3,1,2])])

执行结果

转置和轴对称函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
arr=np.arange(15).reshape((3,5))
print(arr)
#转置(跟线代置换一样 横对竖)
print(arr.T) #轴兑换.T

#矩阵内积XT X np.dot
arr2=np.random.randn(6,3) # 构建6行3列
print(arr2,arr2.T) # 6行3列 3列6行 --> 6行6列
print(arr2.T,arr2)

#转置(高维数组) 元组(轴编号组成)才能对这些轴进行转置
arr3=np.arange(16).reshape((2,2,4)) #三维x=2,y=2,z=4
print(arr3)
print(arr3.transpose((1,0,2)))

#swapaxes方法[需要接受一对轴编号]
print(arr3.swapaxes(1,2))

执行结果

通用函数(元素级数组函数)

1
2
3
4
1.通用函数(ufunc):一种对ndarray中的数据执行元素级运算的函数
2.通用函数:矢量化包装器
输入:一个/多个标量值
输出:一个/多个标量值

一元通用函数

二元通用函数

数组进行数据处理

1
2
3
4
5
6
7
8
9
10
11
#假设我们想要在一组值(网格型)上计算函数sqrt(x^2+y^2)
#np.meshgrid函数
两个一维数组 --> 两个二维矩阵(所有的(X,Y)对)

import numpy as np
points=np.arange(-5,5,0.01) #1000个间隔相等的点
#生成(X,Y)对
xs,ys=np.meshgrid(points,points)
#获取sqrt(X^2+Y^2)
z=np.sqrt(xs**2+ys**2)
print(z)

条件逻辑(数组运算)

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
xarr=np.array([1.1,1.2,1.3,1.4,1.5])
yarr=np.array([2.1,2.2,2.3,2.4,2.5])
cond=np.array([True,False,True,True,False])

#根据判断cond的值为True选取xarr的值Flase选取yarr的值
result=np.where(cond,xarr,yarr) #第二个和第三个参数可以是数组
print(result)

#根据判断xarr大于1.3赋值2小于1.3赋值1
result2=np.where(xarr>1.3,2,1) #第二个和第三个参数可以是标量值
print(result2)

数学和统计方法

基本数组统计方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
#正态分布的数据
arr=np.random.randn(5,4)
print(arr)
print(arr.sum()) #数组中全部/某轴向的元素求和
print(arr.mean()) #算数平均数
print(arr.min()) #最小值
print(arr.max()) #最大值
print(arr.argmin()) #最小元素索引
print(arr.argmax()) #最大元素索引
print(arr.cumsum()) #所有元素累计和
print(arr.cumprod()) #所有元素累计积
print(arr.std()) #标准差
print(arr.var()) #方差

布尔型数组的方法

1
2
3
4
5
6
7
8
9
10
import numpy as np
#布尔值会被强制转换为1(True)和0(False)
arr=np.random.randn(100)
print(arr)
print((arr>100).sum())

#any和all
arr2=np.array([False,False,True,False])
print(arr2.any()) #测试是否存在一个/多个True 测试是否存在一个/多个非0元素
print(arr2.all()) #测试是否所有值都是True 测试是否所有值都是非0元素

排序(sort方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np

#一维数组
arr=np.random.randn(8)
print(arr)
#排序sort方法
arr.sort()
print("排序之后的:")
print(arr)

#多维数组
arr=np.random.randn(5,3)
print(arr)
arr.sort(1) #对轴进行排序 就是每行自己排序
print("排序之后的:")
print(arr)

数组的集合运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np

names=np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
#unique()只返回不重复的名字有几个
print(np.unique(names))

arr1=np.array([1,2,3,4,5,5,5,6,6,6,8,8,8,9,9,91,123,456,123])
arr2=np.array([1,2,3,5,4,9,6,9,123,45678,789])
#unique()只返回不重复的名字有几个
print(np.unique(arr1))
#intersect1d(x,y)返回x和y的公共元素
print(np.intersect1d(arr1,arr2))
#union1d(x,y)返回x和y的并集
print(np.union1d(arr1,arr2))
#int1d(x,y)返回布尔型数组(x的元素是否包含在y之内) 大小是x数组的长度
print(np.in1d(arr1,arr2))
#setdiff1d(x,y)返回集合的差(就是在x之中,不在y中)
print(np.setdiff1d(arr1,arr2))
print(np.setdiff1d(arr2,arr1))
#setxor1d(x,y)返回集合的对称差(只在一个数组但是不同时在两个数组 --有可能在x不在y 有可能在y不在x)
print(np.setxor1d(arr1,arr2))

数组的文件输入输出(文本/二进制数据)

保存到磁盘(save和load)

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
#默认情况下,数组保存在.npy的文件(未压缩的原始二进制格式)
arr=np.arange(10) #按照顺序输出10个数字0-9
print(arr)

#save() 将arr数组存到名为some_array的文件
np.save('some_array',arr) #存一个数组
np.savez('array_archive.npz',a=arr,b=arr) #存多个数组(数组以关键字参数的形式传入)

#load去加载磁盘的文件(自动添加扩展名)
np.load('some_array.npy')
res=np.load('array_archive.npz') #得到类似字典的对象 对各个数组进行延迟加载
print(res['b'])

存取文本文件

1
2
3
#1.python中的文件读写函数
#2.pandas中的read_csv和read_table函数
#3.numpy中的loadtxt和genfromtxt函数

线性代数(linalg)

常用的numpy.linalg函数

1
2
3
4
5
6
7
8
import numpy as np
from numpy.linalg import inv,qr
x=np.array([[1.,2.,3.],[4.,5.,6.]])
y=np.array([[6.,23.],[-1,7],[8,9]])
print(x)
print(y)
#np.dot(x,y) <-> x.dot(y)
print(x.dot(y))

随机数生成(random)

random函数

1
2
3
4

import numpy as np
samples=np.random.normal(size=(4,4))
print(samples)

pandas入门

1
2
3
4
5
6
7
8

1.pandas基于NumPy构建
2.写代码导包
from pandas import Series,DataFrame
import pandas as pd
3.主要数据类型:
Series 类似于一维数组的对象 (数据+数据标签)
DataFrame

Series(像字典)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
from pandas import Series,DataFrame
import pandas as pd

#不指定索引
obj=Series([4,7,-5,3])
#索引(0-N-1) 值
print(obj)
#所有值
print(obj.values)
#所有索引
print(obj.index)

#指定索引
obj2=Series([4,7,-5,3],index=['d','b','a','c'])
print(obj2)
print(obj2.index)

#保留numpy数组运算(保留索引和值之间的链接)
print(obj2[obj2>0])
print(obj2*2)
print(np.exp(obj2))

DataFrame(表格型)

DataFrame创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import numpy as np
from pandas import Series,DataFrame
import pandas as pd

#1.直接传入一个字典(等长列表/numpy数组)
data={
'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9]
}
frame=DataFrame(data)
print(frame)

#指定列序列(dataframe根据指定顺序进行排列)
frame1=DataFrame(data,columns=['year','state','pop']) #data字典要根据列来排序
print(frame1)

#指定列序列(传入的列在数据中找不到,产生NA值)
frame2=DataFrame(data,columns=['year','state','pop','debt']) #debt没有就所有都显示NA
frame3=DataFrame(data,columns=['year','state','pop','debt'],index=['one','two','three','four','five']) #debt没有就所有都显示NA index变成英文
print(frame2)
print(frame3)


#2.嵌套字典(字典中的字典) ---> 外层字典的键作为列 内层字典的键作为行索引
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
#2.嵌套字典(字典中的字典) ---> 外层字典的键作为列 内层字典的键作为行索引
pop={'Nevada':{2001:2.4,2002:2.9},
'Ohio':{2000:1.5,2001:1.7,2002:3.6}} # 列:Nevada,Ohio 行:2000,2001,2002
frame3=DataFrame(pop)
print(frame3)

第一种方式

第二种方式

DataFrame使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
#1.直接传入一个字典(等长列表/numpy数组)
data={
'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9]
}
#指定列序列(传入的列在数据中找不到,产生NA值)
frame2=DataFrame(data,columns=['year','state','pop','debt']) #debt没有就所有都显示NA
print(frame2)
frame2['debt']=16.5 #修改长度和DataFrame长度相匹配!!!!!!!!!
print(frame2)

索引对象

Index对象

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
#轴标签和其他元数据(比如轴名称)
#a 0
#b 1
#c 2
obj=Series(range(3),index=['a','b','c']) # Series/DataFrame构造用到的任何数组/其他序列的标签 --> Index
index=obj.index
print(index) # a b c
print(index[1:]) # b c

index[1]='d' #index对象不可以修改

Index的方法和属性

基本功能

重新索引(reindex)

reindex函数的参数

method选项(前向/后向填充)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# d 4.5
# b 7.2
# a -5.3
# c 3.6
obj=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
print(obj)
# a -5.3
# b 7.2
# c 3.6
# d 4.5
# e NAN
obj2=obj.reindex(['a','b','c','d','e']) #缺失的赋值为NAN
print(obj2)
# a -5.3
# b 7.2
# c 3.6
# d 4.5
# e 0
obj3=obj.reindex(['a','b','c','d','e'],fill_value=0) #缺失的赋值为0
print(obj3)

丢弃指定轴上的项(drop)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
#一个索引数组/列表 --> 丢弃某条轴上的一个/多个项
#a 0.0
#b 1.0
#c 2.0 (丢弃)
#d 3.0
#e 4.0
obj=Series(np.arange(5.),index=['a','b','c','d','e'])
print(obj)
#丢弃c
new_obj=obj.drop('c')
print(new_obj)

索引+选取+过滤

Series索引(啥都有)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# a 0.0
# b 1.0
# c 2.0
# d 3.0
obj=Series(np.arange(4.),index=['a','b','c','d'])
print(obj)

#输出b的索引为1.0
print(obj['b'])

#输出1行的索引值为1.0
print(obj[1])

#输出第三行和第四行
print(obj[2:4])
#利用标签的切片是闭环!!!!!
print(obj['b':'c']) #py切片运算是不包含的最后一个

#输出三行
print(obj[['b','a','d']])

#输出第二行和第三行
print(obj[[1,3]])

#输出前两行
print(obj[obj<2])

DataFrame索引(一个/多个列)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
data=DataFrame(np.arange(16).reshape((4,4)), #随机数分为4*4
index=['Ohio','Colorado','Utah','New York'], #列
columns=['one','two','three','four'] #行
)
print(data)
print()
#1
#5
#9
#13
print(data['two'])
print()
#2 0
#6 4
#10 8
#14 12
print(data[['three','one']])
print()

#选取

#1.第一种
##选取第一行和第二行
print(data[:2])
print()

##选取第三列中大于5的行
print(data['three']>5)
print()

#2.第二种(更像是ndarray数组)
##判断是否data<5
print(data<5)
print()

##将data中小于5的都改为0
data[data<5]=0
print(data)

算术运算和数据对齐

算数方法

Series(不同就赋值NaN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# a 7.3 a -2.1
# c -2.5 c 3.6
# d 3.4 e -1.5
# e 1.5 f 4
# g 3.1
s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
# a 7.3-2.1=5.2
# c 3.6-2.5=1.1
# d NaN (不重叠的赋值NaN)
# e 1.5-1.5=0
# g NaN (不重叠的赋值NaN)
# f NaN (不重叠的赋值NaN)
print(s1+s2)

DataFrame(不同就赋值NaN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# b c d
#Ohio 0.0 1.0 2.0
#Texas 3.0 4.0 5.0
#Colorado 6.0 7.0 8.0
# b d e
#Utah 0.0 1.0 2.0
#Ohio 3.0 4.0 5.0
#Texas 6.0 7.0 8.0
#Oregon 9.0 10.0 11.0
df1=DataFrame(np.arange(9.).reshape((3,3)),
columns=list('bcd'),
index=['Ohio','Texas','Colorado'],
)
df2=DataFrame(np.arange(12.).reshape((4,3)),
columns=list('bde'),
index=['Utah','Ohio','Texas','Oregon'],
)
#得到新的DataFrame[索引和列为原来的两个DataFrame的并集]
#不重叠的位置就会产生NaN值
print(df1+df2)

#填充数字 --> 使用add(DataFrame对象,full_value=值)
print(df1.add(df2,fill_value=0))

函数应用和映射(apply和ufuns方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
frame=DataFrame(np.random.randn(4,3),
columns=list('bde'),
index=['Utah','Ohio','Texas','Oregon']
)
print(frame)

#1.numpy元素级数组方法(ufuncs)
print(np.abs(frame))
#2.函数应用到一维数组(由各列/各行形成) -- apply方法
f=lambda x:x.max() - x.min()
print(frame.apply(f))
print(frame.apply(f,axis=1))

排序和排名(sort_index和sorting)

Series(根据index排序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# d 0
# a 1
# b 2
# c 3
obj=Series(range(4),index=['d','a','b','c'])
print(obj)
# a 1
# b 2
# c 3
# d 0
print(obj.sort_index()) #缺失值默认放在Series末尾

DataFrame(根据任意轴index排序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# d a b c
# three 0 1 2 3
# one 4 5 6 7
frame=DataFrame(np.arange(8).reshape((2,4)), #两行四列 2*4
index=['three','one'],
columns=['d','a','b','c']
)
#1.普通排序
print(frame.sort_index())
#2.更改排序
print(frame.sort_index(axis=1)) #升序(默认)
print(frame.sort_index(axis=1,ascending=False)) #降序(更改ascending属性)
#3.根据一个/多个列值排序 by属性
print(frame.sort_index(by='b'))
print(frame.sort_index(by=['b','a']))

排名(rank)

分析rank()怎么执行

https://blog.csdn.net/justinlonger/article/details/90646111

Series

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
obj=Series([7,-5,7,4,2,0,4])
#
#0 7
#1 -5
#2 7
#3 4
#4 2
#5 0
#6 4
print(obj)
# 有N个相同的元素,求和(相同元素排名)/N
print(obj.rank()) #索引0对应的元素最终排名为(6+7)/2=6.5 以此类推
print(obj.rank(ascending=False,method='max')) #所有小数进位为右边的最小整数(4.5-->5)

DataFrame

1
2
3
4
5
6
7
8
9
10
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
frame=DataFrame({
'b':[4.3,7,-3,2], # b a c 都是列名
'a':[0,1,0,1], # [x]都是值
'c':[-2,5,8,-2.5]
})
print(frame)
print(frame.rank())

带有重复值的轴索引

Series

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# a 0
# a 1
# b 2
# b 3
# c 4
obj=Series(range(5),index=['a','a','b','b','c'])
print(obj)
#测试索引是否唯一
print(obj.index.is_unique) #输出False
#索引对应多个值 --> Series
print(obj['a'])
#索引对应单个值 --> 标量值
print(obj['c'])

汇总和统计

描述和汇总统计:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import numpy as np
from pandas import Series,DataFrame
import pandas as pd
# one two
# a 1.4 np.man
# b 7.1 -4.5
# c np.man np.man
# d 0.75 -1.3
df=DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],index=['a','b','c','d'],columns=['one','two'])
#第一列 1.4+7.1+0.75=9.25
#第二列 -4.5-1.3=-5.80

#直接统计
print(df.sum())

#间接统计(达到最小值/最大值的索引)
print(df.idxmax())
print(df.idxmin())

相关系数(corr)和协方差(cov)

1
2
3
4
5
6
7
8
9
10
1.Series:
corr:计算两个Series中重叠的、非NA的、按索引对齐的值
cov:
2.DataFrame:
corr:返回DataFrame
cov:返回DataFrame

3.Series和DataFrame之间:
corrwith:3.1传入一个Series,返回一个相关系数值Series
3.2传入一个DataFrame计算按列名配对的相关系数

唯一值(unique)和值计数(value_counts)和成员资格(isin)

1
2
3
1. obj.value_counts()
2. obj.unique()
3. obj.isin(['x','y'])

处理缺失数据

NA处理方法

1
2
3
4
5
6
7
1.滤除: dropna() 默认丢弃任何含有Na的行
1.1 Series: data.dropna() / 布尔型索引 data[data.notnull()]
1.2 DataFrame:
dropna(how='all') 可以只丢弃全为na的那些行
dropna(axis=1) 只丢弃全为na的那些列

2.填充: fillna() 默认返回新对象

层次化索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
data=Series(np.random.randn(10),
index=[['a','a','a','b','b','b','c','c','d','d'],
[1,2,3,1,2,3,1,2,2,3]]
)
print(data)
#选取数据索引
print(data.index)
#选取数据子集
print(data['b'])
print(data['b':'c'])
print(data[:,2])

重排分级顺序(sortlevel)

1
2
1.swaplevel 根据两个级别的编号/名称
2.sortlevel 根据单个级别的值对数据进行排序

根据级别汇总统计(groupby)

1
1.在统计和汇总(sum) --> sum(level='xxx')

使用DataFrame的列(set_index)

1
2
1.一个/多个列 --> 行索引
2. frame.set_index(['x','y'])

数据(加载/存储/文件格式)

1
2
3
4
1.输入输出:
1.1 读取文本文件和更高效的磁盘存储格式
1.2 加载数据库中的文件
1.3 利用Web API操作网络资源

读取数据(文本格式)

读取函数介绍

pandas解析函数

1
2
1. 表格型数据 --> DataFrame对象
2. 不同的函数不同的方式

read_csv/read_table函数的参数

逐块读取文本文件(属性nrows和属性chunksize)

1
2
3
1.pd.read_csv('xx.csv',nrows=xx)
2.pd.read_csv('xx.csv',chunksize=xxx)
3.TextParser.get_chunk() 读取任意大小的块

数据写出到文本格式(to_csv)

1
2
3
4
5
6
7
8
1.data.to_csv('xx.csv')   # (默认) ,分隔符 
2.data.to_csv('xx.csv',sep='|') #sep可以更改为 |
3.data.to_csv('xx.csv',na_rep='NULL') #缺失值在输出结果中会被表示为空字符串
4.data.to_csv('xx.csv',index=False,cols=['a','b','c']) #禁掉行和列的标签

#Series
5.Series.to_csv()
6.Series.from_csv()

手工处理分隔符格式(csv.Dialect子类)

Dialect属性:

1
2
3
4
5
6
7
8
9

#1.CSV子类定义:
class dialect(csv.Dialect):
lineterminator='\n' 行结束符
delimiter=';' 分隔字段的单字符字符串
quotechar='"' 带有特殊字符的字段的引用符号

#2.csv.reader也可以接受CSV子类的各种参数
reader=csv.reader(f,delimiter='|')

JSON数据(loads和dumps方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

1.JSON简介:JavaScript Object Notation,已经成为通过HTTP请求在Web浏览器和其他应用程序之间发送数据的标准格式之一。
2.JSON基本类型:对象(字典)、数组(列表)、字符串、数值、布尔值、null
3. json.loads(): JSON字符串 --> Python形式
4. json.dumps(): Python形式 --> JSON字符串

import json

obj="""
{"name":"Wes",
"places_lived":["United States","Spain","Germany"],
"pet":null,
"siblings":[{"name":"Scott","age":25,"pet":"ZuKo"},
{"name":"Katie","age":33,"pet":"Cisco"}]
}
"""
#转为Py格式
result=json.loads(obj)
print(result)

#转回json格式
asjson=json.dumps(result)

#一个/一组 json对象 --> DataFrame/数据结构(便于分析)
siblings=DataFrame(result['siblings'],columns=['name','age']) #可以选一部分的siblings 也可以选全部内容

XML和HTML(get和text_content方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	1.python有许多可以读写html和xml格式数据的库(比如:lxml)
2. lxml.html处理html --> lxml.objectify处理xml

import json
from lxml.html import parser
from urllib2 import urlopen

#使用国内镜像下载lxml
#pip install pip install -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com --target=e:\anaconda\lib\site-packages pythonds
#在设置里面要更新编译器!!! 参考博客:https://blog.csdn.net/qq_40402685/article/details/102929846
parsed=parse(urlopen('http://finance.yahoo.com/q/op?s=AAPL+Options'))
doc=parsed.getroot()
#通过这个对象可以获取特定类型的所有html标签

#获取HTML元素的对象
#获取html中链接是<a=''> a标签 --> 使用文档根节点的findall()方法 + XPath
links=doc.findall('//a')
print(links[15:20])

#获取URL和链接文本 --> get方法(URL)和text_content方法(文本)
Ink=links[28]
Ink.get('href') # 获取地址http://finance.yahoo.com
Ink.text_content() # 获取内容 Special Editions

解析XML(lxml.objectify)

1
2
3
4
5
6
7
8
9
10

1.lxml.objectify 解析xml文件
2..getroot 得到xml文件的根节点的引用
3.root.INDICATOR 返回一个用于产生各个<INDICATOR>XML元素的生成器

import json
from lxml import objectify
path='Performance_MNR.xml'
parsed=objectify.parse(open(path))
root=parsed.getroot()

二进制数据格式(save和load方法)

1
2
3
4
5
6
7
8
9
10
11
12

import numpy as np
import pandas as pd

#pickle只能用于短期存储格式(很难保证pickle格式永远是稳定的)

#1. pandas对象的.save方法(将数据以pickle形式保存在磁盘)
frame=pd.read_csv('aaa/ex1.csv')
frame.save('aaa/frame_pickle') #保存为frame_pickle

#2. pandas.load()将数据读回Python
pd.load('aaa/frame_pickle') #读取frame_pickle

HDF5格式(层次型数据格式HDFStore类)

1
2
3
4
5
6
7

1.高效读写磁盘上二进制格式存储的科学数据
2.HDF5是一个C库(带有很多语言的 接口--JAVA/Python/Matlab)
3.一个HDF5文件 --> 一个文件系统式节点结构(存储多个数据集)
4.HDF5库的两个接口:
4.1 PyTables 抽象了HDF5的许多细节-->提供数据容器、表索引、查询功能、核外计算技术
4.2 h5py 提供一种直接而高级的HDF5 API访问接口
1
2
3
4
5
6
7
8
#h5适合"一次写 多次读"的数据集
import pandas as pd
#pandas有一个HDFStore类(类似于最小化的字典的HDFStore类)
#通过PyTables存储pandas对象
store=pd.HDFStore('mydata.h5')
store['obj1']=frame
store['obj1_col']=frame['a'] #像字典一样获取h5对象
print(store)

读取Microsoft Excel文件(ExcelFile类的xlrd和openpyxl包)

1
2
3
4
5
6
#1.传入xls或xlsx文件
xls_file=pd.ExcelFile('data.xls')
print(xls_file)

#2.通过parse读取到DataFrame
table=xls_file.parse('Sheet1')

HTML和Web API(requests包)

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import requests
import json
#通过Python访问公共API(http://docs.python-requests.org)
url='https://www.liaoxuefeng.com/wiki/1016959663602400/1016966022717728' #随便访问一个网站
#发送一个HTTP GET请求
resp=requests.get(url)
print(resp)

#Response对象(text=‘GET请求的内容’) --> 所以loads加载一下
#许多Web API返回的都是JSON字符串(必须加载到一个Python对象)
data=json.loads(resp.text)
print(data.keys())

数据库()

关系型数据库(pandas.io.sql模块的read_frame函数)

两种方式:

1
2
3
 目前而言有两种方法:
1.通过获得元组列表然后输出
2.sql.read_frame()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import pandas as pd
from pandas import Series,DataFrame
import json
import pandas.io.sql as sql
#嵌入式的SQLite数据库(Python内置的sqlite3驱动器)
import sqlite3

#定义test表
query="""
create table test
(
a varchar(20),
b varchar(20),
c real,
d integer
);"""

#先连接
con=sqlite3.connect(':memory:')
con.execute(query)
con.commit()

#插入几行数据
data=[('Atlanta','Georgia',1.25,6),
('Tallahassee','Florida',2.6,3),
('Sacramento','California',1.7,5)]
stmt="insert into test values(?,?,?,?)"
con.executemany(stmt,data)
con.commit()

#1.第一种 通过获得元组列表然后输出
#返回一个元组列表(大部分python sql驱动[PyODBC psycopg2 MySQLdb pymssql])
res=con.execute('select * from test')
rows=res.fetchall()
print(rows) #输出所有的结果行

#元组列表res --> DataFrame构造器(还需要列名description属性)
print(res.description)
print(DataFrame(rows,columns=zip(*res.description)[0]))


#2.read_frame函数(直接出)
res1=sql.read_frame('select * from test',con)
print(res1)

非关系型数据库(MongoDB为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
from pandas import Series,DataFrame
import json
import requests
import pymongo #MongoDB的官方驱动器

#通过默认端口27017连接MongoDB
con=pymongo.Connection('localhost',port=27017)
#访问tweets集合
tweets=con.db.tweets
#通过tweets.save将tweets逐个存入集合
url='http://search.twitter.com/search.json?q=python%20pandas'
#通过request请求获取数据
data=json.loads(requests.get(url).text)
#将所有data数据存到tweets集合
for tweet in data['results']:
tweets.save(tweet)
#将tweets集合中取出我发的tweet
res=tweets.find({'from_user','宋亚翔'})
print(res)

数据规整化(清理/转换/合并/重塑)

合并数据集

三种合并方法

1
2
3
1.pandas.merge 根据1个/多个键将不同的DataFrame中的行连接起来(像极了数据库连接操作 选几个行)
2.pandas.concat 沿着一条轴将多个对象堆叠在一起
3.实例方法combine_first 将重复数据编接在一起(像数据库的全外连接--先从第一个对象中选值,不行再去第二个对象中选值)

DataFrame的合并(merge和join)

merge函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import pandas as pd
from pandas import Series,DataFrame

#1.多对一的合并merge
##1.两个对象的列名相同
df1=DataFrame({'key':['b','b','a','c','a','a','b'],
'data1':range(7)
})
df2=DataFrame({'key':['a','b','d'],
'data2':range(3)
})
###多对一的合并 merge
print(pd.merge(df1,df2)) # 只有a和b
print(pd.merge(df1,df2,on='key')) #显示指定根据key 只有a和b

##2.两个对象的列名不同(分别指定 left_on=xxx,rigt_on=xxx)
df3=DataFrame({'lkey':['b','b','a','c','a','a','b'],
'data1':range(7)
})
df4=DataFrame({'rkey':['a','b','d'],
'data2':range(3)
})
###多对一的合并 merge
print(pd.merge(df3,df4,left_on='lkey',right_on='rkey')) #左边根据lkey 右边根据rkey

##3.外连接求取(键的并集)
print(pd.merge(df1,df2,how='outer'))

#2.多对多的合并(行的笛卡尔积)
df5=DataFrame({'key':['b','b','a','c','a','b'],
'data1':range(6)
})
df6=DataFrame({'key':['a','b','a','b','d'],
'data2':range(5)
})
#左边有个3个b,右边有2个b 所以最终结果有6个b行
print(pd.merge(df5,df6,on='key',how='left'))
print(pd.merge(df5,df6,how='inner'))

索引上的合并(merge和join只不过更改属性)

1
2
1.普通索引: 设置left_index或者right_index=True表明索引作为连接键
2.层次化索引:设置列表的形式合并键的多个列 (left_on=['key1','key2',right_index=True])

代码举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
from pandas import Series,DataFrame
# key value
#0 a 0
#1 b 1
#2 a 2
#3 a 3
#4 b 4
#5 c 5
# group_val
#a 3.5
#b 7.0

left1=DataFrame({'key':['a','b','a','a','b','c'],
'value':range(6)
})
right1=DataFrame({'group_val':[3.5,7]},
index=['a','b']
)
#根据左边key和右边的索引作为键(index key group_val)
print(pd.merge(left1,right1,left_on='key',right_index=True))

轴向连接(concat)

concat函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#随机生成3*4的数列
arr=np.arange(12).reshape((3,4))
print(np.concatenate([arr,arr],axis=1))

#假设有三个没有重叠索引的Series --> concat函数
s1=Series([0,1],index=['a','b'])
s2=Series([2,3,4],index=['c','d','e'])
s3=Series([5,6],index=['f','g'])
#(默认)concat是在axis=0上工作 --> 产生一个新的Series
# concat是在axis=1上工作 --> 产生一个新的DataFrame
print(pd.concat([s1,s2,s3]))
print(pd.concat([s1,s2,s3],axis=1)) #axis=1是列 0 1 2分别表示的s1 s2 s3

#a 0
#b 5
#f 5
#g 6
s4=pd.concat([s1*5,s3])
print(pd.concat([s1,s4],axis=1)) #axis=1是列 0 1分别是s1 s4
#传入innner可以得到他们的交集
print(pd.concat([s1,s4],axis=1,join='inner')) #axis=1是列 0 1分别是s1 s4 --> 交集就取前两行
#指定要在其他轴上使用的索引(join_axes参数) (使用指定索引 --> 可能会出现都是NaN值)
print(pd.concat([s1,s4],axis=1,join_axes=[['a','c','b','e']]))

#生成层次化索引(keys参数)

# one a 0
# b 1
# two a 0
# b 1
# three f 5
# g 6
# dtype: int64
res=pd.concat([s1,s1,s3],keys=['one','two','three']) #keys就是行
print(res)

# one two three
#a 0.0 0.0 NaN
#b 1.0 1.0 NaN
#f NaN NaN 5.0
#g NaN NaN 6.0
res1=pd.concat([s1,s1,s3],axis=1,keys=['one','two','three']) #keys就是列(axis=1生成一个DataFrame)
print(res1)

重叠数据的合并(combine_first)

方法总结

1
2
3
1. numpy中的where方法
2. Series中的combine_first方法
3. DataFrame中的combine_first方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
# a b
#f NaN f 0.0
#e 2.5 e 1.0
#d NaN d 2.0
#c 3.5 c 3.0
#b 4.5 b 4.0
#a NaN a NaN
a=Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],
index=['f','e','d','c','b','a'])
b=Series(np.arange(len(a),dtype=np.float64),
index=['f','e','d','c','b','a'])
b[-1]=np.nan #b中最后一个赋值NaN
print(a)
print(b)

#使用numpy中的where方法连接
print(np.where(pd.isnull(a),b,a))

#Series中的combine_first方法【+数据对齐】
print(b[:2].combine_first(a[2:]))

重塑(reshape)和轴向旋转(pivot)

1
2
1.重塑 reshape方法
2.轴向旋转 pivot方法

重塑层次化索引(stack和unstack)

1
2
1.stack: 将数据的列"旋转"为行  【列-->行】
2.unstack:将数据的行“旋转”为列 【行-->列】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#number one two three
#state
#Ohio 0 1 2
#Colorado 3 4 5
data=DataFrame(np.arange(6).reshape((2,3)),
index=pd.Index(['Ohio','Colorado'],name='state'), #索引有2个Ohio Colorado
columns=pd.Index(['one','two','three'],name='number') #列有三个one two three
)
#列转成行(默认操作是最内层)
res=data.stack() #变成一列0 1 2 3 4 5
print(res)

#行转成列(默认操作是最内层)
print(res.unstack()) #可以传入 分层级别的编号/分层级别的名称

长格式–> 宽格式

概述

1
1.时间序列数据[长格式(long)/堆叠格式(stacked)]存储在数据库和CSV

数据转换

移除重复数据(duplicated和drop_duplicataes)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

import pandas as pd
import numpy as np
from pandas import Series,DataFrame
# k1 k2
#0 one 1
#1 one 1
#2 one 2
#3 two 3
#4 two 3
#5 two 4
#6 two 4
data=DataFrame({'k1':['one']*3+['two']*4,
'k2':[1,1,2,3,3,4,4]
})
#1.一个列
#DataFrame的duplicated方法 --> 布尔型Series (各行是否是重复行)
print(data.duplicated())
#DataFrame的drop_duplicataes方法 -->移除了重复行的DataFrame
print(data.drop_duplicates())

#2.多个列
data['v1']=range(7) #多加一个列v1 有0-6这7个值
print(data.drop_duplicates(['k1'])) #只根据k1去判断

#3.duplicated和drop_duplicates 默认保留第一个出现的值组合
#keep='last'则保留最后一个
print(data.drop_duplicates(['k1', 'k2'],keep='last')) #更改keep让最后一个保留

利用函数/映射进行数据转换(Series的map方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#有关肉类的数据 食物 -- 盎司
data=DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami','honey ham','nova lox'],
'ounces':[4,3,12,6,7.5,8,3,5,6]
})
print(data)

#想添加一列表示肉类食物来源的动物类型
#编写一个映射(肉类--动物)
meat_to_animal={
'bacon':'pig',
'pulled pork':'pig',
'pastrami':'cow',
'corned beef':'cow',
'honey ham':'pig',
'nova lox':'salmon',
}

#Series的map方法(接受一个函数/含有映射关系的字典型对象)
data['animal']=data['food'].map(str.lower).map(meat_to_animal)
print(data)

替换值(replace方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#0 1.0
#1 -999.0
#2 2.0
#3 -999.0
#4 -1000.0
#5 3.0
data=Series([1.,-999.,2.,-999.,-1000,3.])
print(data)
#-999可能是一个缺失数据的标记值 --> 更改为pandas可以理解的NA值
#一对一替换
data.replace(-999,np.nan)
#多对一替换
data.replace([-999,-1000],np.nan)
#多对多替换
data.replace([-999,-1000],[np.nan,0])
#多对多替换(字典形式)
data.replace({-999:np.nan,-1000:0})
print(data)

轴索引重命名(map全体更新和rename全体更新/部分更新)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
# one two three four
#Ohio 0 1 2 3
#Colorado 4 5 6 7
#New York 8 9 10 11

#Series轴标签和Series值都可以通过函数/映射 --> 新对象
data=DataFrame(np.arange(12).reshape((3,4)),
index=['Ohio','Colorado','New York'],
columns=['one','two','three','four'])

#轴标签也有map方法
print(data.index.map(str.upper)) #所有轴更大
data.index=data.index.map(str.upper)
#更新之后的data (标签更新)
print(data)

#rename方法
#创建数据集的转换版(不修改原始数据)
print(data.rename(index=str.title,columns=str.upper))
#部分轴标签更新
print(data.rename(index={'OHIO':'哈尔滨'},columns={'three':'第三'})) #替换
#原地修改(inplace=True)
datares=data.rename(index={'OHIO':'哈尔滨'},columns={'three':'第三'},inplace=True)

离散化和面元(bin)划分(cut函数和qcut)

cut函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
ages=[20,22,25,27,21,23,37,31,61,45,41,32]
#将数据划分为好几个面元(bin)
#使用pandas的cut函数
bins=[18,25,35,60,100] #划分为 18-25 26-35 35-60 60-100
cats=pd.cut(ages,bins)

#pandas返回的是一个特殊的Categorical对象【表示面元名称的字符串】
print(cats)

#一个表示不同分类名称的levels数组
#一个为年龄数据进行标号的labels实行
print(cats.codes)
print(pd.value_counts(cats)) #圆括号表示开端 方括号表示闭端 --> 可以通过right=False修改哪边是闭端

qcut函数

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#cut和qcut都可以根据数据的最小值和最大值计算等长面元
#cut可能无法使得每个面元中含有相同数量的数据点
#qcut使用的样本分位数 --> 大小基本相等的面元

#正态分布
data=np.random.randn(1000)
cats=pd.qcut(data,4) #按照四位数进行切割
print(cats)
print(pd.value_counts(cats)) #圆括号表示开端 方括号表示闭端 --> 可以通过right=False修改哪边是闭端

异常值(检测和过滤)

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
np.random.seed(12345)
data=DataFrame(np.random.randn(1000,4))
print(data.describe())
#找到某列中|值|>3
flag=data[3]
print(flag[np.abs(flag)>3])

排列(np.random.permutation)和随机采样(np.random.randint)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#利用numpy.random.permutation函数 --> 对Series/DataFrame的列的排列工作 (permuting,随机重排序)
#通过需要排列的轴的长度调用permutation --> 整数数组(表示新序列)
# 0 1 2 3
#0 0 1 2 3
#1 4 5 6 7
#2 8 9 10 11
#3 12 13 14 15
#4 16 17 18 19
df=DataFrame(np.arange(5*4).reshape(5,4)) #生成5行4列的矩阵
sampler=np.random.permutation(5) #调用permutation(5)
print(sampler) #产生一个表示新顺序的整数数组
#基于ix索引操作 / take函数
print(df.take(sampler))

bag=np.array([5,7,-1,6,4])
sampler1=np.random.randint(0,len(bag),size=10) #0-5之间的10个数字
print(sampler1)
print(bag.take(sampler1))

指标/哑变量(get_dummies方法)

1
2
1.分类变量(categorical variable) --> 哑变量矩阵(dummy matrix)/指标矩阵(indicator matrix)
2.如果DataFrame的某一列中含有k个不同的值 -->一个k列矩阵/DataFrame(值全为0/1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
# data1 key
#0 0 b
#1 1 b
#2 2 a
#3 3 c
#4 4 a
#5 5 b
df=DataFrame({'key':['b','b','a','c','a','b'],
'data1':range(6)
})
#根据key列得到一个k列矩阵/DataFrame(全为1/0)
print(pd.get_dummies(df['key'])) #key取值有a b c 所以新的DataFrame列就是a b c

#给指标DataFrame的列加上一个前缀 --> get_dummies的prefix参数
dummies=pd.get_dummies(df['key'],prefix='xin') #key取值有a b c 所以新的DataFrame列就是xin_a xin_b xin_c
df_with_dummy=df[['data1']].join(dummies) #列就加入data1 成为四列
print(df_with_dummy)

字符串操作

字符串对象方法

py内置的字符串方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#val是要判断的字符串
val='a,b guido'

#1.字符串拆分
##根据split拆分成数段(用逗号分隔的字符串)
print(val.split(','))
##根据strip修剪空白符(包括换行符)
pieces=[x.strip() for x in val.split(',')]
print(pieces)

#2.字符串添加
##子字符串添加‘::’ --> .join()
print('::'.join(pieces))

#3.字符串查找
##子串定位 --> in关键字(index和find)
print('guido' in val)
##find和index区别[如果找不到的话index引发一个异常,find返回-1]
print(val.index(','))
print(val.find(':'))

#4.字符串统计
##返回指定子串的出现次数:
print(val.count(','))

正则表达式(regex)

1
2
3
4
5
1.py内置的re模块负责对字符串应用正则表达式
2.py内置的re模块分为三大类:
2.1 模式匹配
2.2 替换
2.3 拆分

pandas中矢量化的字符串函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
#清理待分析的散乱数据 --> 字符串规整化工作

#Dava dava@google.com
#Rob rob@gmail.com
#Steve steve@email.com
#Wes NaN
data={'Dava':'dava@google.com',
'Steve':'steve@email.com',
'Rob':'rob@gmail.com',
'Wes':np.nan}
#将data数据Series规格化
data=Series(data)
#判断data是否为空
print(data.isnull())

#通过data.map可以让所有的字符串和正则表达式方法都应用于各个值(如果存在NA就会报错!!!)
#Series有一些可以跳过NA值的字符串操作方法 --> 通过Series的str属性就可以访问这些方法
print(data.str.contains('gmail'))

绘图和可视化(matplotlib)

matplotlib API入门

1
2
3
4
5
6
7
8
9
1.matplotlib是一个用于创建出版质量图表的桌面绘图包(主要是2D方面)
2.matplotlib结合一种GUI工具包(IPython)可以拥有缩放和平移等交互功能
3.matplotlib支持各种操作系统上许多不同的GUI后端,而且将图片导出为各种常见的矢量(vector)和光栅图(raster):PDF,SVG,JPG,PNG,BMP,GIF等

使用方法:
1.Pylab模式的IPython(ipython--pylab) --> 将IPython配置为使用你所指定的matplotlib GUI后端(TK,wxPyhton,PyQt,Mac OS X native,GTK)
2.引入语句:
import matplotlib
import matplotlib.pyplot as plt

Figure和Subplot(更方便的plt.subplots方法)

旧的figure和subplot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn
fig=plt.figure()
#返回的对象是AxesSubplot对象 --> 直接调用实例方法就可以在其他空着的格子里面画画
ax1=fig.add_subplot(2,2,1) # 图像应该是2*2 并且 当前选中的是4个subplot中的第一个(编号从1开始)
ax2=fig.add_subplot(2,2,2)
ax3=fig.add_subplot(2,2,3)
#绘图命令(在最后一个用过的subplot进行绘制)
plt.plot(randn(50).cumsum(),'k--') #k--是一个线型选择(用于告诉matplotlib绘制黑色虚线图)
_=ax1.hist(randn(100),bins=20,color='k',alpha=0.3)
ax2.scatter(np.arange(30),np.arange(30)+3*randn(30))
plt.show()

新的subplots

1
2
3
4
5
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
#更方便的plt.subplots()方法
fig,axes=plt.subplots(2,3) # --> 一个含有已创建的subplot对象的NumPy数组

调整subplot周围的间距(Figure的subplots_adjust方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	# wspace和hspace用于控制宽度和高度的百分比(用作subplot之间的间距)
1.subplots_adjust(left=None,bottom=None,right=None,top=None,wspace=None,hspace=None)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn
# subplots为2行2列 使用相同的X和Y轴刻度
fig,axes=plt.subplots(2,2,sharex=True,sharey=True)
for i in range(2):
for j in range(2):
axes[i,j].hist(randn(500),bins=50,color='k',alpha=0.5)
#间距收缩为0
plt.subplots_adjust(wspace=0,hspace=0)
plt.show()

颜色(color)、标记(marker)、线型(linestyle)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn
#标记类型和线型必须放在颜色后面

#两种书写方式相同
#ax.plot(x,y,'g--') 在一个字符串中指定颜色和线型的方式非常方便
#ax.plot(x,y,linestyle='--',color='g')

#两种书写方式相同
plt.plot(randn(30).cumsum(),'ko--')
#plt.plot(randn(30).cumsum(),color='k',linestyle='dashed',marker='o') #marker是标记

#线形图(非实际数据点默认是按线性方式插值的) -- drawstyle选项修改
plt.plot(randn(30),'k--',label='Default')
plt.plot(randn(30),'k--',drawstyle='steps-post',label='steps-post')
plt.show()

刻度(xticks)、标签(xticklabels)、图例(xlim)

1
2
3
4
5
大多数的图表装饰项:	
1.过程型的pyplot接口(交互式使用) -- xlim(图表的范围)/xticks(刻度位置)/xticklabels(刻度标签)之类的方法
1.1 调用时不带参数(返回当前的参数值): 例如plt.xlim()返回当前的X轴绘图范围
1.2 调用时带参数(设置参数值): 例如plt.xlim([0,10])会将X轴的范围设置0-10
2.面向对象的原生matplotlib API

设置标题(set_title)、轴标签(set_xlabel)、刻度(set_xticks)、刻度标签(set_xticklabels)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn
fig=plt.figure();
ax=fig.add_subplot(1,1,1)
ax.plot(randn(1000).cumsum())

#修改X轴的刻度 --> set_xticks和set_xticklabels
#set_xticks告诉matplotlib要将刻度放在数据范围中的哪些位置(默认情况下这些位置也是刻度标签)
#set_xticklabels将任何其他的值用作标签
ticks=ax.set_xticks([0,250,500,750,1000])
labels=ax.set_xticklabels(['one','two','three','four','five'],rotation=30,fontsize='small')

#给X轴设置名称 --> set_xlabel
#给设置一个标题 --> set_title
ax.set_title('My first matplotlib plot')
ax.set_xlabel('Stages')
plt.show()

添加图例(ax.legend/plt.legend)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn

fig=plt.figure();ax=fig.add_subplot(1,1,1)
#画三条线段
ax.plot(randn(100).cumsum(),'k',label='one')
ax.plot(randn(100).cumsum(),'k',label='two')
ax.plot(randn(100).cumsum(),'k',label='three')
#调用ax.legnd()或plt.legend()来自动创建图例
ax.legend(loc='best')
plt.show()

注解以及在Subplot上绘图(matplotlib.pyplot/matplotlib.patches)

1
2
3
1.matplotlib有一些表示常见图形的对象(对象被称为块[patch])
2.matplotlib.pyplot(Rectangle和Circle)
3.matplotlib.patches
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn
from datetime import datetime
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
rect=plt.Rectangle((0.2,0.75),0.4,0.15,color='k',alpha=0.3)
circ=plt.Circle((0.7,0.2),0.15,color='b',alpha=0.3)
pgon=plt.Polygon([[0.15,0.15],[0.35,0.4],[0.2,0.6]],color='g',alpha=0.5)
ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)
plt.show()

将图标保存到文件(plt.savefig)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from datetime import datetime
from io import BytesIO
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
rect=plt.Rectangle((0.2,0.75),0.4,0.15,color='k',alpha=0.3)
circ=plt.Circle((0.7,0.2),0.15,color='b',alpha=0.3)
pgon=plt.Polygon([[0.15,0.15],[0.35,0.4],[0.2,0.6]],color='g',alpha=0.5)
ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)

#将当前图标保存到文件 <--> Figure对象的实例方法savefig
##普通格式(指定扩展名是什么就会出现什么)
plt.savefig('figpath.svg') #图表保存为SVG文件
##自带各种属性
plt.savefig('figpath.png',dpi=400,bbox_inches='tight')
##Web上提供动态生成的图片
buffer=BytesIO()
plt.savefig(buffer)
plot_data=buffer.getvalue()

matplotlib配置

1
2
3
4
5
6
 操作matplotlib配置系统的方式
1.Python编程方式(利用rc方法):
1.1 plt.rc('figure',figsize=(10,10)) #第一个参数是希望自定义的对象
1.2 font_options={'family':'monospace','weight':'bold','size':'small'}
plt.rc('font',**font_options) #将选项写成一个字典
2.进入matplotlib/mpl-data目录 --> 自定义

pandas中的绘图函数

线型图(默认kind=’line’)

1
1.Series和DataFrame都有一个用于生成各类图表的plot方法(默认是线形图)

Series的plot参数:

DataFrame的plot参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn
s=Series(np.random.randn(10).cumsum(),index=np.arange(0,100,10)) #该Series对象的索引会被传给matplotlib --> 绘制X轴
s.plot()
plt.show()
#DataFrame的plot方法会在一个subplot中为各列绘制一条线,并自动创建图例
df=DataFrame(np.random.randn(10,4).cumsum(0),columns=['A','B','C','D'],index=np.arange(0,100,10))
df.plot()
plt.show()

柱状图(kind=’bar’/‘barh’)

1
2
1.Series.plot( 设置kind='bar'(垂直柱状图) / kind='barh'(水平柱状图) )
2.DataFrame.plot( 设置kind='bar'(垂直柱状图) / kind='barh'(水平柱状图) )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np
from pandas import Series,DataFrame
import matplotlib
import matplotlib.pyplot as plt
from numpy.random import randn

#Series
fig,axes=plt.subplots(2,1)
data=Series(np.random.rand(16),index=list('abcdefghijklmnop'))
#kind='bar'
data.plot(kind='bar',ax=axes[0],color='k',alpha=0.7) #alpha是透明度0-1
data.plot(kind='barh',ax=axes[0],color='k',alpha=0.7) #alpha是透明度0-1
plt.show()

#DataFrame(柱状图会将每一行的值分为一组)
df = pd.DataFrame(np.random.rand(6, 4),
index=['one', 'two', 'three', 'four', 'five', 'six'],
columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'))
df.plot(kind='bar')
plt.show()

#stacked=True可以生成堆积柱状图
df.plot(kind='barh',stacked=True,alpha=0.5)
plt.show()

直方图(Series的hist方法)和密度图(kind=’kde’)

1
2
1.直方图(histogram):是一种可以对值频率进行离散化显示的柱状图[数据点被拆分到离散的、间隔均匀的面元中,绘制的是各面元中数据点的数量]
2.密度图(KDE,核密度估计图):将该分布近似为一组核(诸如正态分布等)
1
2
3
tips['tip_pct']=tips[tip] / tips['total_bill']
tips['tip_pct'].hist(bins=50)
tips['tip_pct'].plot(kind='kde')

散布图(plt.scatter方法和pd.scatter_matrix函数)

1
2
3
4
5
1.散布图(scatter plot):是观察两个一维数据序列之间的关系
2.使用方法
2.1 plt.scatter() 观察一组变量的散布图(也被称为散布图矩阵)
2.2 pd.scatter_matrix()
pandas提供了一个从DataFrame创建散布图矩阵的scatter_matrix函数(还支持在对角线上放置各变量的直方图/密度图)

Python图形化工具生态系统

1
2
1.Chaco: 静态图+交互式图形
2.mayavi:基于开源C++图形库VTK的3D图形工具包

数据聚合与分组运算

GroupBy技术

1
2
3
4
5
6
7
8
9
1.分组(split) : pandas对象(Series/DataFrame) --> 根据一个/多个键拆分(split)为多组 [对象特定轴上执行的,DataFrame可以在其行(axis=0)其列(axis=1)进行分组]
1.1 分组键:(多种形式+类型不必相同)
1.1.1 列表/数组(长度和待分组的轴一样)
1.1.2 表示DataFrame某个列名的值
1.1.3 字典/Series(待分组轴上的值--分组名的对应关系)
1.1.4 函数(用于处理轴索引/索引中的各个标签)

2.应用(apply) : 将一个函数应用到各个分组 --> 产生一个新值
3.合并(combine) : 所有函数的执行结果合并到最终的结果对象中

流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

#1.分组键为Series
df=DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)})
#根据一个分组
##根据key1进行分组,并计算data1列的平均值 --> 访问data1,并且根据key1调用groupby
grouped1=df['data1'].groupby(df['key1']) #grouped是一个GroupBy对象
##调用GroupBy的mean方法计算分组平均值
print(grouped1.mean())
print()

#根据多个分组
grouped2=df['data1'].groupby([df['key1'],df['key2']])
##调用GroupBy的mean方法计算分组平均值
print(grouped2.mean())
print()

#2.分组键为数组(长度适当)
states=np.array(['Ohio','California','California','Ohio','Ohio'])
years=np.array([2005,2005,2006,2005,2006])
grouped3=df['data1'].groupby([states,years])
print(grouped3.mean())
print()

#3.分组键为列名(字符串/数字/其他Python对象)
print(df.groupby('key1').mean())
print(df.groupby(['key1','key2']).mean())
print()

分组迭代(groupby方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
	1.GroupBy对象支持迭代 --> 一组二元元组(分组名+数据块)

import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn
# data1 data2 key1 key2
#0 0.794423 0.872517 a one
#1 0.228070 0.846891 a two
#2 1.002588 0.632977 b one
#3 -1.664231 0.320534 b two
#4 1.470316 -1.338423 a one
df=DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)
})

for name,group in df.groupby('key1'): #根据key1进行分组输出name是a的和group是b的
print(name)
print(group)

print("--------------------------------")

for (k1,k2),group in df.groupby(['key1','key2']): # 多重键(元组的第一个元素将会是由键值组成的元组) # a与one a与two b与one b与two
print(k1,k2)
print(group)

print("--------------------------------")

#将这些数据片段做成一个字典
pieces=dict(list(df.groupby('key1')))
print(pieces['b'])

print("--------------------------------")

#groupby默认是axis=0按照行分组
grouped1=df.groupby(df.dtypes,axis=1)
pieces2=dict(list(grouped1))
print(pieces2)

执行结果:

选取一个/一组列(groupby([‘x1’,’x2’]))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#两种转换
df.groupby('key1')['data1'] <--> df['data1'].groupby(df['key1'])

import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn
#对于由DataFrame产生的GroupBy对象 --> 用一个/一组列名对其进行索引(选取部分列进行聚合的目的)
# data1 data2 key1 key2
#0 0.794423 0.872517 a one
#1 0.228070 0.846891 a two
#2 1.002588 0.632977 b one
#3 -1.664231 0.320534 b two
#4 1.470316 -1.338423 a one
df=DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)
})
res=df.groupby(['key1','key2'])[['data2']].mean() #df['data2'].groupby(df['key1','key2'])
print(res)

通过字典/Series进行分组(groupby(字典名))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

#1.DataFrame
people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
#添加几个NaN值
people.ix[2:3,['b','c']]=np.nan # b和c两列的第三行Wes
#假设已知列的分组关系(根据分组计算列的总计)
mapping={'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
#只需将这个字典传给groupby
by_column=people.groupby(mapping,axis=1) #传入分组字典和按照列分组
print(by_column.sum())

#2.Series(可以看做一个固定大小的映射)
map_series=Series(mapping)
by_column2=people.groupby(map_series,axis=1)
print(by_column2.count())

通过函数进行分组(groupby(函数))

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
#添加几个NaN值
people.ix[2:3,['b','c']]=np.nan # b和c两列的第三行Wes
#传入len函数
print(people.groupby(len).sum())

通过索引级别分组(level关键字)

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

Icolumns = pd.MultiIndex.from_arrays([['US', 'US', 'US', 'JP', 'JP'],
[1, 3, 5, 1, 3]],
names=['cty', 'tenor'])
hier_df=DataFrame(np.random.randn(4,5))
print(hier_df)
#通过level关键字传入级别编号/名称
res=hier_df.groupby(level='cty',axis=1)
print(res.count())

数据聚合

groupby聚合函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

#quantile可以计算Series/DataFrame列的样本分位数
df=DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)
})
#根据key1分组
grouped=df.groupby('key1')
print(grouped['data1'].quantile(0.9)) #quantile是一个Series方法

无索引的形式返回聚合数据(as_index=False禁用)

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

#quantile可以计算Series/DataFrame列的样本分位数
df=DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)
})
#根据key1和Key2分组 但是以"无索引化"
print(df.groupby(['key1','key2'],as_index=False).mean())

分组级运算和转换

transform和apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
key=['one','two','one','two','one']

#1.根据transform() --> 1.产生一个可以广播的标量值(np.mean) 2.产生一个相同大小的结果数组
print(people.groupby(key).mean()) #列是a b c d e 行是one two
print("---------------------------------------")
print(people.groupby(key).transform(np.mean)) #列是a b c d e 行是Joe

禁止分组键(group_keys=False)

1
data.groupby('key1',group_keys=False).apply(top)

分位数(quantile)和桶(bucket)分析

1
2
3
1.pandas有一些能根据指定面元/样本分位数-->数据拆分为多块的工具(cut和qcut)
2.groupby
1和2结合起来 --> 桶(bucket)和分位数(quantile)

两种不同的分别方法(cut和qcut):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn
frame=DataFrame({
'data1':np.random.randn(1000),
'data2':np.random.randn(1000)
})

#1.长度相等的桶 -- 区间大小相等(data1相同) -- cut()
##按照四位数进行分隔
factor=pd.cut(frame.data1,4) #cut返回的Factor对象可以直接用于groupby
##统计计算
def get_stats(group): # 定义函数get_stats(4个方法)
return {'min':group.min(),
'max':group.max(),
'count':group.count(),
'mean':group.mean()
}
grouped1=frame.data2.groupby(factor)
print(grouped1.apply(get_stats).unstack()) # 重塑层次化索引 --> unstack()是行转成列(默认操作是最内层)

#2.大小相等的桶 -- 数据点数量相等(count相同) -- qcut()
##按照10位数分隔 + labels=False
grouping=pd.qcut(frame.data1,10,labels=False)
##统计计算
grouped2=frame.data2.groupby(grouping)
print(grouped2.apply(get_stats).unstack())

(示例)用特定于分组的值填充缺失值(fillna方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

#对于缺失数据的清理工作 --> 1.dropna()将其滤除 2.fillna()将其填充

##获取一个Series对象
s=Series(np.random.randn(6))
s[::2]=np.nan #索引为0 2 4三行设置NaN值
print(s)
print("---------------------------------")
#使用fillna()填充所有的NaN值
print(s.fillna(s.mean())) #mean是算数平均值

(示例)随机采样和排列(random.permutation方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from numpy.random import randn

#蒙特卡罗模拟(大数据集中随机抽取样本) --> np.random.permutation(N)的前K个元素 [N为完整数据的大小,k为期待的样本大小]
#构造一副英语型扑克牌
#红桃(Hearts) 黑桃(Spades) 梅花(Clubs) 方片(Diamonds)
suits=['H','S','C','D']
card_val=(range(1,11)+[10]*3)*4
base_names=['A']+range(2,11)+['J','K','Q']
cards=[]
for suit in ['H','S','C','D']:
cards.extend(str(num)+suit for num in base_names)
#拥有一个长度为52的Series(索引为牌名) -- 值则是21点/其他游戏中用于计分的点数(A的点数为1)
deck=Series(card_val,index=cards)
print(np.random.permutation(len(deck)))

透视表(pivot table)和交叉表(crosstab)

pivot_table参数:

1
2
3
4
5
6
7
8
9
 透视表:
1.透视表(pivot table):是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具
2.透视表通过一个/多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩阵区域
3.DataFrame有一个pivot_table方法 【还可以添加分项小计margins】
4.pandas.pivot_table函数
交叉表:
1.交叉表:是一种用于计算分组频率的特殊透视表
2.DataFrame有一个pivot_table方法
3.pandas.crosstab函数(数组/Series/数组列表,数组/Series/数组列表,...)

时间序列(time series)

1
2
3
4
5
 具体应用场景:
1.时间戳(timestamp):特定的时刻
2.固定时期(period):例如2022年9月
3.时间间隔(interval):由起点和结束时间戳表示
4.实验/过程时间:每个时间点都是相对于特定起始时间的一个度量

日期和时间数据类型及工具(datetime模块)

1
2
1.python标准库:日期(data)、时间(time)数据的数据类型、日历方面的功能
2. datetime模块 time模块 calendar模块

datetime模块中的数据类型

1
2
3
4
5
import datetime
#获取当前时间now
now=datetime.datetime.now() # 2022-09-16 14:33:42.323779
print(now)
print(now.year,now.month,now.day)

字符串和datetime之间的转换(strptime/strftime方法)

datetime格式定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import datetime
from dateutil.parser import parse
import pandas as pd
#(-->传入一个格式化字符串)利用 str/strftime方法
#datetime对象和pandas的Timestamp对象可以被格式化字符串

##三种方式:
#1.利用datetime.strftime方法(将字符串转为日期)
print(datetime.datetime(2011,1,3).strftime('%Y-%m-%d')) #%Y是四位数的年 m是2位数的月(01-12) d是2位数的日(01-31)
#2.利用datetime.strptime方法(通过已知格式进行日期解析的最佳方式)
value='2011-01-03'
print(datetime.datetime.strptime(value,'%Y-%m-%d'))
#3.通过dateutil第三方包的parser.parse方法
print(parse('2011-01-03'))
print(parse('6/12/2011',dayfirst=True)) #通常日出现在月前面 (年 日 月) --> 设置dayfirst=True

datestrs=['7/6/2011','8/6/2011']
##to_datetime方法 (解析多种不同的日期表示形式)
print(pd.to_datetime(datestrs)) #to_datetime方法
#处理缺失值(None/空字符串)
print(pd.to_datetime(datestrs+[None])) #NaT(Not a Time)是pandas中时间戳数据的Na值

时间序列基础

索引更换为datetime数据

1
2
3
4
5
6
7
8
9
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd

dates=[datetime.datetime(2011,1,2),datetime.datetime(2011,1,5),datetime.datetime(2011,1,7),datetime.datetime(2011,1,8),datetime.datetime(2011,1,10),datetime.datetime(2011,1,12)]
#根据dates给出的时间作为索引
ts=Series(np.random.randn(6),index=dates) #datetime对象实际上是放在一个DatatimeIndex中
print(ts)

索引、选取、子集构造(和Series一致)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd

dates=[datetime.datetime(2011,1,2),datetime.datetime(2011,1,5),datetime.datetime(2011,1,7),datetime.datetime(2011,1,8),datetime.datetime(2011,1,10),datetime.datetime(2011,1,12)]
#根据dates给出的时间作为索引
ts=Series(np.random.randn(6),index=dates) #datetime对象实际上是放在一个DatatimeIndex中
print(ts)

#TimeSeries是Series的一个子类(索引和数据选取方面行为一样)
#获取ts的第三行 (2011-01-07)
stamp=ts.index[2]
print(f'stamp抓取的是:{stamp}')
print(f'stamp对应行的数据是:{ts[stamp]}')

日期的范围/频率/移动

生成日期范围(pandas.data_range)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd

#(默认)date_range会产生按天计算的时间点
index1=pd.date_range('4/1/2012','5/1/2012') # 从2012年4月1日到2012年6月1日 dtype='datetime64[ns]', freq='D'
print(index1)
print("---------------------------------------------------------------------------")
#如果只传入起始/结束日期(start/end) --> 还得传入一个表示一段时间的数字(periods='x')
index2=pd.date_range(start='4/1/2012',periods=10)
print(index2)
print("---------------------------------------------------------------------------")
index3=pd.date_range(end='6/1/2012',periods=10)
print(index3)
print("---------------------------------------------------------------------------")

#只显示日期索引(只有每个月最后一天) --> 更改BM频率freq='BM'
index4=pd.date_range('1/1/2000','12/1/2000',freq='BM')
print(index4)
print("---------------------------------------------------------------------------")

#产生一组被规范化到午夜的时间戳() --> 更改normalize=True
index5=pd.date_range('5/2/2012',periods=10,normalize=True)
print(index5)

频率和日期偏移量(freq属性)

时间序列的基础频率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from pandas.tseries.offsets import Hour,Minute
#pandas中的频率=基础频率(字符串别名表示)+乘数
#对于每个基础频率,都有一个被称为日期偏移量(data offset)的对象与之对应

##1.比较笨重的方法
#按小时计算的频率(Hour类表示)
hour=Hour()
print(hour) #1 Hour
#定制偏移量的倍数(传入一个整数)
d_hour=Hour(4)
print(d_hour)

##2.比较方便的方法
#创建字符串别名
index1=pd.date_range('1/1/2000','2/1/2000',freq='4h') #按照4个小时进行变换
print(index1)

#大部分偏移量对象通过加法进行连接
print(f'加起来一共是:{Hour(2)+Hour(4)+Minute(30)}')

#freq='WOM-3FRI' --> "每月第三个星期五"之类的日期
index2=pd.date_range('1/1/2000','2/1/2000',freq='WOM-3FRI')
print(list(index2))

移动(超前和滞后)数据(shift方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from pandas.tseries.offsets import Hour,Minute

#Series和DataFrame都有一个shift方法(单纯的前移/后移操作,保持索引不变)
#2000-01-31 -0.201348
#2000-02-29 -0.126236
#2000-03-31 -0.457643
#2000-04-30 1.012834
ts=Series(np.random.randn(4),
index=pd.date_range('1/1/2000',periods=4,freq='M') # 从2000.01.01开始记录四个日期 然后频率为M(每月最后一个日历日)
)
print(ts)
print("---------------------------------------------------")
print(ts.shift(2)) # 日期不变 数据往后压(前面补NaN)
print("---------------------------------------------------")
print(ts.shift(-2)) # 日期不变 数据往前提(后面补NaN)
print("---------------------------------------------------")
print(ts.shift(3,freq='D')) # 日期根据频率D变化
print("---------------------------------------------------")

通过偏移量对日期进行位移(rollback和rollforward方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from pandas.tseries.offsets import Hour,Minute
from pandas.tseries.offsets import Day,MonthEnd

#pandas的日期偏移量可以作用在datatime/Timestamp对象上
now=datetime.datetime(2011,11,17) # 当前时间设定为2011年11月17日
print(now+3*Day()) # 加上三天之后成为2011年11月20日

#添加锚点偏移量(频率要考虑月末是不是周末,并不是均匀分隔的) --> 第一次增量会将原日期向前滚动到符合频率规则的下一个日期
print(now+MonthEnd()) # 2011年11月20日+月末=2011年11月30日
print(now+MonthEnd(2)) # 2011年11月20日+月末(往后推2个月)=2011年12月31日
#通过rollforward和rollback方法(显式将日期向前/向后滚动)
offset=MonthEnd()
print(f'现在是:{now}') # 2011年11月17日
print(offset.rollforward(now)) #往前推 日子快了 就是11.30日
print(offset.rollback(now)) #往后推 日子慢了 就是10.31日

时区处理(第三方库pytz)

1
2
1.在Python中时区信息来自第三方库pytz --> 使得Python可以使用Olson数据库(汇编了世界时区信息)
2. import pytz

pandas中的方法可以接受时区名(建议)/对象

1
2
3
4
5
import pytz
print(pytz.common_timezones[-5:]) #最后五个时区表
#获取时区对象 --> pytz.timezone
tz=pytz.timezone('US/Eastern')
print(tz)

本地化(tz_localize)和转换(tz_convert)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
import pytz

#(默认)pandas中的时间序列是单纯的(naive)时区
rng=pd.date_range('3/9/2012 9:30',periods=6,freq='D') # 从2012年9月3日9点30分开始 顺序出来6个日期
#随机出6个数字 索引按照rng的日期
ts=Series(np.random.randn(len(rng)),index=rng)
print(ts)
print(ts.index.tz) #None

#单纯到本地化的转换 --> tz_localize方法
ts_utc=ts.tz_localize('UTC')
print(ts_utc)

#转换到其他时区 --> tz_convert方法
ts_con=ts_utc.tz_convert('US/Eastern')
print(ts_con)

时期+算数运算(pd.Period类)

1
2
1.时期:时间区间(比如:数日,数月,数季,数年等)
2.Period类所表示的就是这种数据类型(构造函数需要用到一个字符串/整数)

Period类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
import pytz

#这个Period对象表示的是从2007年1月1日到2007年12月31日之间的整段时间
p=pd.Period(2007,freq='A-DEC')
#这个Period对象表示的是从2022年1月1日到2022年12月31日之间的整段时间
p2=pd.Period(2022,freq='A-DEC')
print(f'当前年份:{p}')
#只需要对Period对象加/减一个整数就可以达到根据其频率进行位移
print(f'当前年份基础上加五年:{p+5}')
print(f'当前年份基础上减两年:{p-2}')
print(f'两个相同频率的Period对象之间的差就是单位数量的差:{p2-p}') #2022-2007=15

时期的频率转换(asfreq方法)

1
2
3
4
5
6
7
8
9
10
import datetime
import pandas as pd

#这个Period对象表示的是从2007年1月1日到2007年12月31日之间的整段时间
p=pd.Period(2007,freq='A-DEC')

#任务:
#年度时期 --> 当年年初/年末的一个月度时期
print(p.asfreq('M',how='start'))
print(p.asfreq('M',how='end'))

通过数组创建PeriodIndex

1
index=pd.PeriodIndex(xxx,freq='Q-DEC')

重采样(resampling)+频率转换

1
2
3
重采样(resampling):将时间序列从一个频率 --> 另一个频率的处理过程
降采样(downsampling):高频率数据聚合 --> 低频率
升采样(upsampling):低频率数据 --> 高频率

重采样(resample方法)

resample方法的参数

1
2
3
4
5
6
7
8
9
10
11
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from numpy.random import randn

rng=pd.date_range('1/1/2000',periods=100,freq='D')
ts=Series(randn(len(rng)),index=rng)
print(ts.resample('M').mean()) #以前是resample('M',how='mean')
print("-------------------------------------------------------------------------")
print(ts.resample('M',kind='period').mean()) #聚合到时期(period)

降采样(resample方法更改属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from numpy.random import randn
import pytz

rng=pd.date_range('1/1/2000',periods=12,freq='T')
ts=Series(np.arange(12),index=rng) #索引是时间(从2000年1月1日开始每一分钟一个数据)
print(ts)
print("---------------------------------")
#1分钟聚合到5分钟(通过求和)
print(ts.resample('5min').sum()) # 默认是右区间闭合(X,X] 默认以各面元左边界的时间戳进行标记
print("---------------------------------")
print(ts.resample('5min',closed='left').sum()) # 可以通过closed改为是左区间闭合[X,X) 默认以各面元左边界的时间戳进行标记
print("---------------------------------")
print(ts.resample('5min',closed='left',label='right').sum()) # 可以通过closed改为是左区间闭合[X,X) 更改为以各面元右边界的时间戳进行标记
print("---------------------------------")

#对结果索引做一些位移 (loffset设置一个字符串/日期偏移量)
print(ts.resample('5min',loffset='-1s').sum())
print("---------------------------------")

OHLC降采样(属性how=’ohlc’)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from numpy.random import randn

#金融领域(有一种无处不在的时间序列聚合方式)
#计算各面元的四个值
##第一个值(open,开盘)
##最后一个值(close,收盘)
##最大值(high,最高)
##最小值(low,最低)
rng=pd.date_range('1/1/2000',periods=6,freq='T')
ts=Series(np.arange(6),index=rng) #索引是时间(从2000年1月1日开始每一分钟一个数据)
print(ts)
print("------------------------------------")
print(ts.resample('5min').ohlc())

groupby降采样(groupby加上lambda字符串)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from numpy.random import randn

rng=pd.date_range('25/1/2000',periods=13,freq='D')
ts=Series(np.arange(13),index=rng) #索引是时间(从2000年1月1日开始每一分钟一个数据)
print(ts)
print("--------------------------------------------------")

#根据月份/星期几进行分组
print(ts.groupby(lambda x:x.month).mean()) #根据月份
print("--------------------------------------------------")
print(ts.groupby(lambda x:x.weekday).mean()) #根据星期X

升采样和插值(fill_method属性和limit属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from numpy.random import randn

frame = pd.DataFrame(np.random.randn(2, 4),
index=pd.date_range('1/1/2000', periods=2,freq='W-WED'), #频率是周
columns=['Colorado', 'Texas', 'New York', 'Ohio'])
print(frame)
print("-----------------------------------------------------------------------------------------------------------------")

#将其重采样到日频率(默认会引入缺失值)
df_daily=frame.resample('D').sum()
print(df_daily)
print("-----------------------------------------------------------------------------------------------------------------")

#填充(fill_method属性)
print(frame.resample('D').ffill())
print("-----------------------------------------------------------------------------------------------------------------")
#填充指定的时期数
print(frame.resample('D').ffill(limit=2)) #前三行填充
print("-----------------------------------------------------------------------------------------------------------------")

通过时期进行重采样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import datetime
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
from numpy.random import randn

frame = pd.DataFrame(np.random.randn(24, 4),
index=pd.period_range('1-2000', '12-2001', freq='M'), #按照月从2000年1月到2001年12月一共24个
columns=['Colorado', 'Texas', 'New York', 'Ohio']) #列为四个项

#降采样(只有2000和2001行)
annual_frame=frame.resample('A-DEC').mean()
print(annual_frame)
print("----------------------------------------------------------------------------------")
#升采样(要决定在新频率中各区间的哪端用于放置原来的值)
print(annual_frame.resample('Q-DEC').ffill()) # Q-DEC是季度型(每年以12月结束)
print("----------------------------------------------------------------------------------")
print(annual_frame.resample('Q-DEC',convention='start').ffill()) # Q-DEC是季度型(每年以12月结束)
print("----------------------------------------------------------------------------------")

移动窗口函数

移动窗口和指数加权函数:

python从入门到实践课本课后题

变量

2.1 简单消息

具体代码

1
2
3

message="hello songyaxiang"
print(message)

执行结果


2.2 多条简单消息

具体代码

1
2
3
4
5

message="hello songyaxiang"
print(message)
message="hello python"
print(message)

执行结果


2.3 个性化消息

具体代码

1
2
3

message="Eric"
print(f"hello {message},would you like to learn some Python today?")

执行结果


2.4 调整名字的大小写

具体代码

1
2
3
4
5

message="song_ya_xiang"
print(message.title())
print(message.upper())
print(message.lower())

执行结果


2.5 名言

具体代码

1
2
3

message='Albert Einstein once said,"A person who never made a mistake never tried anything new"' #单双引号混用
print(message)

执行结果


2.6 名言2

具体代码

1
2
3
4
5

famous_person="Albert"
#单双引号混用
message=f"{famous_person} "'Einstein once said,"A person who never made a mistake never tried anything new"'
print(message)

执行结果


2.7 剔除人名中的空白

具体代码

1
2
3
4
5
6
7
8
9
10

message=" songyaxiang " #左边一个空格 右边四个空格
print(f"\t{message}") #\t是四个空格
print(f"{message}\n") #\n是换行
#删除左边空格
print(message.lstrip())
#删除右边空格
print(message.rstrip())
#删除两边空格
print(message.strip())

执行结果


2.8 数字四则运算

具体代码

1
2
3
4
5
6
7
8

message=2
print(message) #试着输出message看看是不是2
print(f"加法的结果是:{message+4}") #2+4=6
print(f"减法的结果是:{message-4}") #2-4=-2
print(f"乘法的结果是:{message*4}") #2*4=8
print(f"除法的结果是:{message/4}") #2/4=0.5
print(f"乘方的结果是:{message**4}") #2的4次方=16

执行结果


2.9 最喜欢的数

具体代码

1
2
3
4

message=7777777
print(message) #试着输出message看看是不是7777777
print(f"我最喜欢的数是:{message}")

执行结果


列表基本内容

3.1 姓名

具体代码

1
2
3
4
5
6
7

names=['SongYaXiang','Python','Java','C++']
print(names) #输出列表会带中括号!!!
print(names[0]) #下标从0-3
print(names[1])
print(names[2])
print(names[3])

执行结果


3.2 问候语

具体代码

1
2
3
4
5
6

names=['SongYaXiang','Python','Java','C++']
print(f"{names[0]} hello!")
print(f"{names[1]} hello!")
print(f"{names[2]} hello!")
print(f"{names[3]} hello!")

执行结果


3.3 自己的列表

具体代码

1
2
3
4
5

tongxun=['car','biycle','airplane','trip','van']
print(f"I like {tongxun[0]}")
print(f"I like {tongxun[1]}")
print(f"I like {tongxun[2]}")

执行结果


3.4-3.7 嘉宾名单

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

jiabin=['宋亚翔','python','java','c++','c语言']
print(jiabin)
#为每一位嘉宾打印消息
print(f"{jiabin[0]} 欢迎您来!!")
print(f"{jiabin[1]} 欢迎您来!!")
print(f"{jiabin[2]} 欢迎您来!!")
print(f"{jiabin[3]} 欢迎您来!!")
print(f"{jiabin[4]} 欢迎您来!!")
print("----------修改(直接赋值)----------")
jiabin[0]='黎明' #宋亚翔不能来了 我们邀请了黎明来
print(jiabin)
print("----------开头添加insert()方法----------")
jiabin.insert(0,'王明')
print(jiabin)
print("----------中间添加insert()方法----------")
jiabin.insert(2,'王五')
print(jiabin)
print("----------末尾添加append()方法----------")
jiabin.append('赵四')
print(jiabin)
print("----------末尾删除del语句----------")
del jiabin[7]
print(jiabin)
print("----------删除pop()方法----------")
jiabin.pop(5)
print(jiabin)
print("----------删除指定值remove()方法----------")
jiabin.remove('python')
print(jiabin)

执行结果


3.8 放眼世界(排序/翻转)

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

lvyou=['南京','上海','北京','哈尔滨','西藏']
print(f"输出一下:{lvyou}")

print("-----使用sorted函数正向排序-----")
print(f"使用sorted函数暂时排序:{sorted(lvyou)}")
print(f"重新输出一下:{lvyou}")

print("-----使用sorted函数反向排序-----")
print(f"使用sorted函数暂时排序:{sorted(lvyou,reverse=True)}")
print(f"重新输出一下:{lvyou}")

print("-----使用reverse()方法翻转-----")
lvyou.reverse()
print(f"翻转一下:{lvyou}")
lvyou.reverse()
print(f"再翻转一下:{lvyou}")

print("-----使用sort()方法正向排序-----")
lvyou.sort()
print(lvyou)

执行结果


3.9 嘉宾长度

具体代码

1
2
3

jiabin=['宋亚翔','python','java','c++','c语言']
print(len(jiabin))

执行结果


列表进阶内容

4.1 比萨

具体代码

1
2
3
4
5

foods=['tomato','bacon','cheese']
for food in foods:
print(f"I like {food}!")
print("I really love pizza!")

执行结果


4.2 动物

具体代码

1
2
3
4
5
6

animals=['monkey','mouse','elephant']
for animal in animals:
print(animal)
print(f"A {animal} would make a great pet")
print("Any of these animals would make a great pet!")

执行结果


4.3 for循环输出1-20

具体代码

1
2
3

for value in range(1,21):
print(value)

执行结果


4.4 一百万

具体代码

1
2
3
4

numbers=list(range(1,1000001));
for value in numbers:
print(value)

执行结果


4.5 一百万求和

具体代码

1
2
3
4
5

numbers=list(range(1,1000001));
print(max(numbers))
print(min(numbers))
print(sum(numbers))

执行结果


4.6 循环打印奇数

具体代码

1
2
3

for value in range(1,21,2):
print(value)

执行结果


4.7 循环打印3的倍数

具体代码

1
2
3

for value in range(3,31,3):
print(value)

执行结果


4.8 循环打印某些数的立方

具体代码

1
2
3

for value in range(1,11):
print(value**3)

执行结果


4.9 立方解析(列表解析)

具体代码

1
2
3

s=[value**2 for value in range(1,11)];
print(s)

执行结果


4.10 切片

具体代码

1
2
3
4
5
6
7

jiabins=['宋亚翔','python','java','c++','c语言']
for jiabin in jiabins[0:3]:
print(jiabin)
print("--------------------")
for jiabin in jiabins[-3:]:
print(jiabin)

执行结果


4.11 你的比萨,我的比萨

具体代码

1
2
3
4
5
6
7
8
9
10
11
12

foods=['tomato','bacon','cheese']
friend_pizzas=foods[:] #复制副本
#两个列表都添加新的比萨
foods.append('abs')
friend_pizzas.append('bbb')
#循环遍历输出
for food in foods:
print(food)
print("\n")
for friend in friend_pizzas:
print(friend)

执行结果


4.13 自助餐

具体代码

1
2
3
4
5
6
7
8
9

foods=('aaa','bbb','ccc','ddd','eee')
for food in foods:
print(food)
# foods[0]='fff' #元组不允许修改
print("\n")
foods=('aaaa','bbbb','ccc','ddd','eee') #只能所有的重新赋值
for food in foods:
print(food)

执行结果


if语句

5.3 外星人颜色

具体代码

1
2
3
4
5
6

alien_color='green'
if alien_color == 'green':
print("是绿色,恭喜您获得五分!")
if alien_color == 'yellow':
print("是黄色,恭喜您获得五分!")

执行结果


5.4 外星人颜色2

具体代码

1
2
3
4
5
6

alien_color='green'
if alien_color == 'green':
print("是绿色,恭喜您获得5分!")
else :
print("不是绿色,恭喜您获得10分!")

执行结果


5.5 外星人颜色3

具体代码

1
2
3
4
5
6
7
8

alien_color='yellow'
if alien_color == 'green':
print("是绿色,恭喜您获得5分!")
elif alien_color == 'red':
print("是红色,恭喜您获得10分!")
else :
print("是其他颜色,恭喜您获得15分!")

执行结果


5.6 人生的不同阶段

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

age=120
if age<2:
print("此人是婴儿")
elif age>2 and age <4 :
print("此人是幼儿")
elif age>4 and age<13 :
print("此人是儿童")
elif age>13 and age<20 :
print("此人是青少年")
elif age>20 and age<65 :
print("此人是成年人")
else :
print("此人是老年人")

执行结果


5.7 喜欢的水果

具体代码

1
2
3
4
5
6
7
8
9
10
11
12

favorite_fruits=['apple','orange','bananas',]
if 'apple' in favorite_fruits :
print("apple在此列表内!")
if 'oranges' in favorite_fruits :
print("oranges在此列表内!")
if 'orange' in favorite_fruits :
print("orange在此列表内!")
if 'bananas' in favorite_fruits :
print("bananas在此列表内!")
if 'applebet' in favorite_fruits :
print("applebet在此列表内!")

执行结果


5.8 以特殊方式跟管理员打招呼

具体代码

1
2
3
4
5
6
7

users=['admin','bbb','ccc','ddd','eee_dasd']
for user in users:
if user == 'admin' :
print("Hello admin,would you like to see a status report?")
else :
print(f"Hello {user},thank you for logging in again.")

执行结果


5.9 处理没有用户的情形

具体代码

1
2
3
4
5
6
7

users=['admin','bbb','ccc','ddd','eee_dasd']
for user in users:
if user == 'admin' :
print("Hello admin,would you like to see a status report?")
else :
print(f"Hello {user},thank you for logging in again.")

执行结果


5.10 检查用户名

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

current_users=['admin','John','CCC','ddd','EeE_dasd']
new_users=['aaa','bbb','JOHN','ddd','eee']
#创建当前用户副本
current_users_xiaoxie=current_users[:]
#将当前用户小写形式存储
i=0;
for user in current_users_xiaoxie:
current_users_xiaoxie[i]=user.lower() #转为小写
i=i+1

#输出小写副本文件
print("已经存在的用户小写形式为:")
print(current_users_xiaoxie)

#遍历查看是否注册过
for user in new_users:
if user.lower() in current_users_xiaoxie :
print(f"{user}注册过,请重新输入")
else :
print(f"{user}可以使用")

执行结果


5.11 序数

具体代码

1
2
3
4
5
6
7
8
9
10
11

numbers=['1','2','3','4','5','6','7','8','9'];
for number in numbers:
if number == '1' :
print("1st")
elif number == '2' :
print("2nd")
elif number == '3' :
print("3rd")
else :
print(f"{number}th")

执行结果


字典

6.1 人

具体代码

1
2
3
4

peoples={'frist_name':'宋','last_name':'亚翔','age':'23','city':'西安'}
for jian,zhi in peoples.items():
print(f"{jian}: {zhi}")

执行结果


6.2 喜欢的数

具体代码

1
2
3
4

peoples={'宋亚翔':'7','荔湾':'34636','王五':'23','赵四':'5498'}
for jian,zhi in peoples.items():
print(f"{jian}: {zhi}")

执行结果


6.3 词汇表

具体代码

1
2
3
4

peoples={'JAVA':'大二学的','C':'大一学的','C#':'大二学的','C++':'还没学的','Python':'正在学的'}
for jian,zhi in peoples.items():
print(f"{jian}: {zhi}")

执行结果


6.4 词汇表2

具体代码

1
2
3
4
5
6
7

peoples={'JAVA':'大二学的','C':'大一学的','C#':'大二学的','C++':'还没学的','Python':'正在学的'}
print(peoples)
#新添加两对键值对
peoples['机器学习'] = '研一学的'
peoples['深度学习'] = '研二学的'
print(peoples)

执行结果


6.5 河流

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13

rivers={'the Yangtze River':'China','Yellow River':'China','Nile':'Egypt'}
#打印对应河流和国家
for key,value in rivers.items():
print(f"The {key} runs through {value}")
print("\n")
#打印所有河流名称
for key in rivers.keys():
print(key)
print("\n")
#打印所有国家名称
for value in rivers.values():
print(value)

执行结果


6.6 调查

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13

favorite_languages={
'jen':'python',
'sarah':'c',
'edward':'ruby',
'phil':'python'
}
people={'jen','ww','syx','zs'}
for key in people:
if(key in favorite_languages):
print(f"{key}恭喜你!")
else :
print(f"{key}抱歉!")

执行结果


6.7 人们

具体代码

1
2
3
4
5
6
7

peoples_one={'frist_name':'宋','last_name':'亚翔','age':'23','city':'西安'}
peoples_two={'frist_name':'李','last_name':'五','age':'12','city':'武汉'}
peoples_three={'frist_name':'赵','last_name':'四','age':'22','city':'长沙'}
peoples=[peoples_one,peoples_two,peoples_three]
for people in peoples:
print(people)

执行结果


6.8 宠物

具体代码

1
2
3
4
5
6
7
8

#列表里面存储字典
peoples_one={'frist_name':'欢欢','last_name':'宋亚翔'}
peoples_two={'frist_name':'乐乐','last_name':'李五',}
peoples_three={'frist_name':'憨憨','last_name':'赵四'}
pets=[peoples_one,peoples_two,peoples_three]
for pet in pets:
print(pet)

执行结果


6.9 喜欢的地方

具体代码

1
2
3
4
5
6

#字典里面存储列表
syx_place=['上海','北京','哈尔滨']
favorite_places={'宋亚翔':syx_place,'王五':'武汉','赵四':'上海',}
for name,place in favorite_places.items():
print(f"{name}: {place}")

执行结果


6.10 喜欢的数2

具体代码

1
2
3
4
5
6
7

#字典里面存储列表
syx_number=['12','77','7777']
lz_number=['408','555']
peoples={'宋亚翔':syx_number,'荔湾':lz_number,'王五':'23','赵四':'5498'}
for jian,zhi in peoples.items():
print(f"{jian}: {zhi}")

执行结果


6.11 城市

具体代码

1
2
3
4
5
6
7
8

#字典里面存储字典
xian={'country':'china','population':'250.6w','fact':'陕西省省会'}
shanghai={'country':'china','population':'555.3w','fact':'中国的一线城市'}
beijing={'country':'china','population':'105.8w','fact':'中国的首都'}
cities={'xian':xian,'shanghai':shanghai,'beijing':beijing}
for city,xx in cities.items():
print(city,xx)

执行结果


while循环

7.1 汽车租赁

具体代码

1
2
3

message=input("请问您需要租赁什么样的汽车?")
print(message)

执行结果


7.2 餐馆订位

具体代码

1
2
3
4
5
6

message=input("请问您有几位用餐: ")
if int(message) > 8 :
print("现在没有空桌")
else :
print("现在有空桌")

执行结果


7.3 10的整数倍

具体代码

1
2
3
4
5
6

message=input("请输入1个数判断是否为10的整数倍: ")
if int(message)%10 == 0:
print("是10的整数倍!")
else :
print("不是10的整数倍!")

执行结果


7.4 比萨配料

具体代码

1
2
3
4
5

message=''
while message != 'quit' :
message=input("请输入需要添加的比萨配料:");
print(message)

执行结果


7.5 电影票

具体代码

1
2
3
4
5
6
7
8
9
10

price=''
while price != 0 :
price=input("请输入观看者年龄:");
if int(price) <= 3 :
print("免费")
elif int(price)> 3 and int(price) < 12 :
print("10美元")
else :
print("15美元")

执行结果


7.8 熟食店

具体代码

1
2
3
4
5
6
7
8

sandwich_orders=['aaa','bbb','ccc']
finished_sandwiches=[]
for sandwich in sandwich_orders:
print("I made your tuna sandwich")
finished_sandwiches.append(sandwich)

print(finished_sandwiches)

执行结果


7.9 五香烟熏牛肉卖完了

具体代码

1
2
3
4
5
6
7
8
9
10
11

sandwich_orders=['aaa','pastrami','bbb','ccc','pastrami','pastrami','pastrami']
print("删除前的列表:")
print(sandwich_orders)
print("熏牛肉已经卖完了!")
#要删除的变量名
current='pastrami'
while current in sandwich_orders :
sandwich_orders.remove(current)
print("删除后的列表:")
print(sandwich_orders)

执行结果


7.10 梦想的度假胜地

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#获取最终调查结果
result={}
#结束的标志符
flag=True
while flag:
name=input("请问您的姓名:")
respnse=input("请问您最想去的城市:")
result[name]=respnse #将姓名和所想去的城市存入字典
repeat=input("还有人参加吗yes/no?")
#如果没人参加了就设置flag为false
if repeat == 'no':
flag=False
print(result)

执行结果


函数

8.1 消息

具体代码

1
2
3
4
5

def display_message():
print("这是第八章,我们学习函数")

display_message()

执行结果


8.2 喜欢的图书

具体代码

1
2
3
4
5

def favorite_book(title):
print(f"这是我最喜欢的书: {title}")

favorite_book('python入门')

执行结果


8.3 T恤

具体代码

1
2
3
4
5
6
7
8
9

def make_shirt(type='python'):
if type=='python':
print("I love Python")
else:
print(f"I love {type}")

make_shirt()
make_shirt('JAVA')

执行结果


8.4 大号T恤

具体代码

1
2
3
4
5
6
7
8
9

def make_shirt(type='python'):
if type=='python':
print("I love Python")
else:
print(f"I love {type}")

make_shirt()
make_shirt('JAVA')

执行结果


8.5 城市

具体代码

1
2
3
4
5
6
7

def describe_city(city,country='中国'):
print(f"{city} is in {country}")

describe_city('北京')
describe_city('克里米亚','乌克兰')
describe_city('洛杉矶','美国')

执行结果


8.6 城市名

具体代码

1
2
3
4
5
6
7

def city_country(city,country):
print(f"{city},{country}")

city_country('北京','中国')
city_country('洛杉矶','美国')
city_country('东京','日本')

执行结果


8.7 专辑

具体代码

1
2
3
4
5
6
7
8
9
10
11

def make_album(name=None,zname=None):
zj={'name':name,'zname':zname}
return zj

a=make_album()
b=make_album('syx','aa')
c=make_album('sss','aa')
print(a)
print(b)
print(c)

执行结果


8.8 用户的专辑

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

def make_album(name=None,zname=None):
zj={'name':name,'zname':zname}
return zj

name=''
a =''
while name!= quit:
name=input("输入歌手名称: ")
sname=input("输入专辑名: ")
if name =='quit':
break;
a=make_album(name,sname)
print(a)

执行结果


8.9 消息

具体代码

1
2
3
4
5
6
7

def show_messages(messages):
for message in messages:
print(message)

messages=['我第一','我才是第一','我不卷了']
show_messages(messages)

执行结果


8.10 发送消息

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

def show_messages(messages,sent):
print("这是show_messages函数:")
for message in messages:
print(message)
sent.append(message)

def send_messages(a,b):
print("这是send_messages函数:")
print("这是messages列表:")
for aa in a:
print(aa)
print("这是sent_messages列表:")
for bb in b:
print(bb)

messages=['我第一','我才是第一','我不卷了']
sent_messages=[]
#调用两个函数
show_messages(messages,sent_messages)
send_messages(messages,sent_messages)

执行结果


8.11 消息归档

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

def show_messages(messages,sent):
print("这是show_messages函数:")
for message in messages:
print(message)
sent.append(message)

def send_messages(a,b):
print("这是send_messages函数:")
print("这是messages列表:")
for aa in a:
print(aa)
print("这是sent_messages列表:")
for bb in b:
print(bb)

messages=['我第一','我才是第一','我不卷了']
sent_messages=[]
#调用两个函数
show_messages(messages,sent_messages)
copy=messages[:]
send_messages(copy,sent_messages)

执行结果


8.12 三明治

具体代码

1
2
3
4
5
6
7

def add_foods(foods):
print(f"现在添加了{foods}食材")

add_foods('maxisao')
add_foods('mamaniya')
add_foods('hanbaobao')

执行结果


8.13 用户简介

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

def build_profile(first,last,**user_info):
"""创建一个字典,其中包含我们知道的有关用户的一切"""
user_info['first_name']=first
user_info['last_name']=last
return user_info

user_profile=build_profile('宋','亚翔',
location='西安',
field='计算机',
sex='男'
)

print(user_profile)

执行结果


8.14 汽车

具体代码

1
2
3
4
5
6
7
8

def car(people,size,**xinxi):
xinxi['制造商']=people
xinxi['型号']=size
return xinxi

result=car('宋亚翔','1',city='西安',price='100065')
print(result)

执行结果


9.1 餐馆

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

class Restaurant:
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name=restaurant_name
self.cuisine_type=cuisine_type

def describe_restaurant(self):
print("餐馆正在营业1")
print("餐馆正在营业2")

def open_restaurant(self):
print("餐馆正在营业3")

my_food = Restaurant('宋亚翔真香饭店',10)
print(my_food.restaurant_name)
print(my_food.cuisine_type)
my_food.describe_restaurant()
my_food.open_restaurant()

执行结果


9.2 三家餐馆

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

class Restaurant:
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name=restaurant_name
self.cuisine_type=cuisine_type

def describe_restaurant(self):
print(f"{self.restaurant_name}正在营业")

def open_restaurant(self):
print("餐馆正在营业")

my_food1 = Restaurant('宋亚翔真香饭店',10)
my_food2 = Restaurant('王努力马洗扫饭店',22)
my_food3 = Restaurant('狗都不吃饭店',13)
my_food1.describe_restaurant()
my_food2.describe_restaurant()
my_food3.describe_restaurant()

执行结果


9.3 用户

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

class user:
def __init__(self,first_name,last_name,sex,age):
self.first_name=first_name
self.last_name=last_name
self.sex=sex
self.age=age

def describe_user(self):
print(f"{self.first_name}{self.last_name}----性别为{self.sex} 年龄为:{self.age}")

def greet_user(self):
print(f"{self.first_name}先生欢迎你!")

user_one=user('宋','亚翔','男','23')
user_one.describe_user()
user_one.greet_user()
user_two=user('李','四','女','29')
user_two.describe_user()
user_two.greet_user()

执行结果


9.4 就餐人数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

class Restaurant:
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name=restaurant_name
self.cuisine_type=cuisine_type
self.number_served=10 #指定默认值

def describe_restaurant(self):
print(f"{self.restaurant_name}餐馆正在营业!")
print("餐馆正在营业2")

def open_restaurant(self):
print(f"{self.restaurant_name}餐馆开门了!")

def set_number_served(self,number):
self.number_served=number

def increment_number_served(self,number):
self.number_served+=number

my_food = Restaurant('宋亚翔真香饭店',10)
#打印多少人就餐
my_food.open_restaurant()
my_food.describe_restaurant()
print(f"开始人数是:{my_food.number_served}")
my_food.set_number_served(100)
print(f"修改一次人数是:{my_food.number_served}")
my_food.increment_number_served(25)
print(f"递增一次人数是:{my_food.number_served}")

执行结果


9.5 尝试登录次数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

class user:
def __init__(self,first_name,last_name,sex,age,login_attempts):
self.first_name=first_name
self.last_name=last_name
self.sex=sex
self.age=age
self.login_attempts=login_attempts

def describe_user(self):
print(f"{self.first_name}{self.last_name}----性别为{self.sex} 年龄为:{self.age}")

def greet_user(self):
print(f"{self.first_name}先生欢迎你!")

def increment_login_attempts(self):
self.login_attempts+=1

def reset_login_attempts(self):
self.login_attempts=0

users=user('宋','亚翔','男','23',77)
users.increment_login_attempts()
print(users.login_attempts)
users.increment_login_attempts()
print(users.login_attempts)
users.increment_login_attempts()
print(users.login_attempts)
users.increment_login_attempts()
print(users.login_attempts)
users.reset_login_attempts()
print(users.login_attempts)

执行结果


9.6 冰淇淋小店

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#父类
class Restaurant:
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name=restaurant_name
self.cuisine_type=cuisine_type
self.number_served=10 #指定默认值

def describe_restaurant(self):
print(f"{self.restaurant_name}餐馆正在营业!")
print("餐馆正在营业2")

def open_restaurant(self):
print(f"{self.restaurant_name}餐馆开门了!")

def set_number_served(self,number):
self.number_served=number

def increment_number_served(self,number):
self.number_served+=number

#子类
class IceCreamStand(Restaurant):
def __init__(self,restaurant_name,cuisine_type,flavors):
super().__init__(restaurant_name,cuisine_type) #一定是super()方法 并且没有self
self.flavors=flavors

def xianshi(self):
print(f"冰激凌有:{self.flavors}")

#列表表示冰淇淋的口味
flavor=['草莓','蓝莓','香蕉']
ice =IceCreamStand('宋亚翔','桶装',flavor)
ice.xianshi()

执行结果


9.7 管理员

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

class user:
def __init__(self,first_name,last_name,sex,age,login_attempts):
self.first_name=first_name
self.last_name=last_name
self.sex=sex
self.age=age
self.login_attempts=login_attempts

def describe_user(self):
print(f"{self.first_name}{self.last_name}----性别为{self.sex} 年龄为:{self.age}")

def greet_user(self):
print(f"{self.first_name}先生欢迎你!")

def increment_login_attempts(self):
self.login_attempts+=1

def reset_login_attempts(self):
self.login_attempts=0

class Admin(user):
def __init__(self,first_name,last_name,sex,age,login_attempts,privileges):
super().__init__(first_name,last_name,sex,age,login_attempts)
self.privileges=privileges

def show_privileges(self):
print(f"管理员权限有:{self.privileges}")

privilege=["update","delete","add"]
admin = Admin('宋','亚翔','男','23',22,privilege)
admin.show_privileges()

执行结果


9.8 权限

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

class user:
def __init__(self,first_name,last_name,sex,age,login_attempts):
self.first_name=first_name
self.last_name=last_name
self.sex=sex
self.age=age
self.login_attempts=login_attempts

def describe_user(self):
print(f"{self.first_name}{self.last_name}----性别为{self.sex} 年龄为:{self.age}")

def greet_user(self):
print(f"{self.first_name}先生欢迎你!")

def increment_login_attempts(self):
self.login_attempts+=1

def reset_login_attempts(self):
self.login_attempts=0

class Admin(user):
def __init__(self,first_name,last_name,sex,age,login_attempts,privileges):
super().__init__(first_name,last_name,sex,age,login_attempts)
self.privileges=Privileges(pris) #这里通过privileges实例 ----> 属性

class Privileges:
def __init__(self,privileges):
self.privleges=privileges

def show_privileges(self):
print(f"管理员权限有:{self.privleges}")

pris=['update','delete','add']
ppp=Privileges(pris)
admin=Admin('宋','亚翔','男','23',44,ppp)
#相当于Privileges(pris)实例 然后调用展示
admin.privileges.show_privileges()

执行结果


9.13 骰子

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

from random import randint
class Die:
def __init__(self,sides=6):
self.sides=sides

def roll_die(self):
print(randint(1,self.sides))

die=Die(6)
die.roll_die()
die=Die(6)
die.roll_die()
die=Die(6)
die.roll_die()
die=Die(6)
die.roll_die()
die=Die(6)
die.roll_die()
die=Die(6)
die.roll_die()

执行结果


9.14 彩票

具体代码

1
2
3
4
5

from random import sample
lottery=['1','2','3','4','5','6','7','8','9','10','a','b','c','d','e']
result=sample(lottery,4)
print(result)

执行结果


9.15 彩票分析

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13

from random import sample
lottery=['1','2','3','4','5','6','7','8','9','10','a','b','c','d','e']
result=sample(lottery,4)
print(f"中大奖的序列是:{result}")
current=[]
sum=0
while result!=current:
current=sample(lottery,4)
print(f"当前随机的序列是:{current}")
sum+=1

print(f"一共要{sum}多次才可以中大奖!")

执行结果


文件和异常

10.1 python学习笔记

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#.txt文件和.py文件在一个目录里面!!!

#1.全文读取
with open('learning_python.txt',encoding='utf-8') as files:
contents=files.read()
print(contents)

#2.逐行读取
with open('learning_python.txt',encoding='utf-8') as files:
for file in files:
print(file.strip()) #去除print打印多余空行

#3.使用列表读取
with open('learning_python.txt',encoding='utf-8') as files:
lines=files.readlines()
#with语句外
for line in lines:
print(line.strip()) #去除print打印多余空行

执行结果


10.2 C语言学习笔记

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#1.一行一行修改
with open('learning_python.txt',encoding='utf-8') as files:
lines=files.readlines()

for line in lines:
line=line.replace('Python','JAVA')
print(line.strip()) #删除print打印多余空格

#2.整段文直接修改
with open('learning_python.txt',encoding='utf-8') as files:
lines=files.read()
lines=lines.replace('Python','JAVA')
print(lines)

执行结果


10.3 访客

具体代码

1
2
3
4
5
6

#1.open()里面写是w 写入模式
#2.使用write()写入文件
with open('learning_python.txt','w',encoding='utf-8') as files:
writes=input("请输入用户名:")
files.write(writes)

执行结果


10.4 访客名单

具体代码

1
2
3
4
5
6
7

with open('learning_python.txt','w',encoding='utf-8') as files:
writes=''
while writes != 'quit':
writes=input("请输入用户名:") #输入用户名
print(f"{writes}欢迎您!") #打印问候语
files.write(f"{writes}\n") #自己在f字符串里面加\n换行

执行结果


10.5 调查

具体代码

1
2
3
4
5
6
7

with open('learning_python.txt','w',encoding='utf-8') as files:
writes=''
while writes != 'quit':
print("为什么您喜欢编程?")
writes=input("请输入原因:") #输入用户名
files.write(f"{writes}\n") #自己在f字符串里面加\n换行

执行结果


机器学习

机器学习计划

学习思路

1
2
3
4
5
6
1.用书
西瓜书(机器学习)
python机器学习(蜥蜴书)
2.视频
b站浙大教授带你全面解读机器学习西瓜书!
黑马程序员3天机器学习入门

参考视频pdf文件

参考笔记


机器学习简介

相关关系

应用领域

1
2
3
4

1.传统预测:店铺销量预测/量化投资/广告推荐/企业客户分类/sql语句安全监测分类
2.图像识别:人脸识别/街道交通标志检测
3.自然语言处理:文本分类/情感分析/自动聊天

相关概念

数据集(特征值+目标值)

常见三类问题

1
2
3
1.**分类问题**:给一堆小猫小狗 --> 分类是小狗还是小猫
2.**回归问题**:给一堆房价和地理位置等信息 --> 得到连续的房价数据
3.**聚类问题**:给一堆属性信息 --> 合成在一起

算法分类

1
2
3
4
5
1.监督学习(**预测**):输入数据有特征有标签(有标准答案)---分类和回归
1.1 分类: k-近邻算法/贝叶斯分类/决策树与随机森林/逻辑回归/神经网络
1.2 回归: 线性回归/岭回归
2.无监督学习:输入数据有特征无标签(无标准答案)---聚类
2.1 聚类: k-means

开发流程


特征工程

数据集

可用数据集

1
2
3
4
5
6
7
8
9
10
11
12
1. Kaggle:https://www.kaggle.com/datasets
1.1 数据量巨大
1.2 真实数据
1.3 80万科学家
1.4 大数据竞赛平台
2. UCI:http://archive.ics.uci.edu/ml/
2.1 数据量几十万
2.2 涵盖科学/生活/经济等领域
2.3 收录360个数据集
3. scikit-learn:https://scikit-learn.org/stable/
3.1 数据量较小
3.2 方便学习

sklearn数据集

sklearn数据集内容

1
2
3
1.分类/聚类/回归
2.特征工程
3.模型选择/调优

sklearn获取流行数据集(datasets)

1
2
3
4
5
1.sklearn.datasets  --- 加载获取流行数据集
1.1 datasets.load_*() ---获取小规模数据集
数据包含在datasets里
1.2 datasets.fetch_*(data_home=None) ---获取大规模数据集
需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是 ~/scikit_learn_data/

sklearn小数据集(load)

1
2
3
4
5
6
7
from sklearn import datasets
iris=datasets.load_iris()
print(iris)
----------------------------------
from sklearn import datasets
boston=datasets.load_boston()
print(boston)

sklearn大数据集(fetch)

1
2
3
from sklearn import datasets
newgroup=datasets.fetch_20newsgroups()
print(newgroup)

sklearn返回值(字典格式)

以鸢尾花为例(iris)

1
2
3
4
5
6
7
#load和fetch均返回数据类型是datasets.base.Bunch(字典格式)

1.data:特征数据数组(特征值)
2.target:标签数组(目标值)
3.DESCR:数据描述
4.feature_names:特征名
5.target_names:目标名

数据集划分

1
2
3
4
5
6
数据集划分:
1.训练数据: 用于训练/构建模型
2.测试数据: 用于评估模型是否有效
数据集划分比例:
训练集: 70% 80% 75%
测试集: 30% 20% 30%

数据集划分API(model_selection)

1
2
3
4
5
sklearn.model_selection.train_test_split(arrays,*option)
1.x: 特征值
2.y: 目标值
3.test_size: 测试集大小(一般是float/默认是0.25)
4.random_state: 随机数种子(相同种子采样结果相同)

使用鸢尾花数据集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sklearn import datasets
from sklearn.model_selection import train_test_split

iris=datasets.load_iris()

#训练集特征值x_train
#测试集特征值x_test
#训练集目标值y_train
#测试集目标值y_test
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=22) #随机数种子是22 测试集大小默认是0.25
print(f"训练集特征值x_train: {x_train}")
print(f"测试集特征值x_test: {x_test}")
print(f"训练集目标值y_train: {y_train}")
print(f"测试集目标值y_test: {y_test}")


特征工程介绍

特征提取(sklearn.feature_extraction)

  • 任意数据(文本/图像) –> 数字特征(机器学习)

特征提取分类

1
2
3
1.字典特征提取(特征离散化) 
2.文本特征提取
3.图像特征提取(深度学习)

字典特征提取(DictVectorizer类)

1
2
3
4
#有三个方法:
1.fit_transform(X): 输入一个字典返回稀疏矩阵
2.inverse_transform(X): 输入一个稀疏数组/数组返回原始数据格式
3.get_feature_names(): 返回类别名称

以城市为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.feature_extraction import DictVectorizer
#对字典类型数据进行特征抽取
data = [{'city': '北京','temperature':100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
#1.实例化一个转换器类
transfer=DictVectorizer(sparse=False) #sparse默认是True打开的是稀疏矩阵
#2.调用fit_transform()方法抽取特征
data_new=transfer.fit_transform(data)
#获得特征名称
print(transfer.get_feature_names())
#获得特征
print(data_new) #sparse默认是True打开的是稀疏矩阵
#反转最初的数据格式
print(f"原来的数据格式是:{transfer.inverse_transform(data_new)}")

文本特征提取(CountVectorizer类统计特征词出现个数)

1
2
3
4
#有三个方法:
1.fit_transform(X): 输入一个文本/文本字符串返回稀疏矩阵
2.inverse_transform(X): 输入一个稀疏数组/数组返回原始数据格式
3.get_feature_names(): 返回类别名称

以英文段落为例:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.feature_extraction.text import CountVectorizer
#准备数据
data =["life is short,i like like python", "life is too long,i dislike python"]
#1.实例化一个转换器
count=CountVectorizer()
#2.调用fit_transfrom()方法获取数据
data_new=count.fit_transform(data)
print(count.get_feature_names_out()) #get_feature_names已经过期了!!!
#二维数组要用toarray()方法展示出来 没有sparse=False这个设置!!!
print(data_new.toarray())
print(count.inverse_transform(data_new))

文本特征提取(TfidfVectorier类+jieba库的cut方法分词)

jieba库的cut方法

以中文段落为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.feature_extraction.text import CountVectorizer
import jieba
#准备数据
data=["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以 每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在 看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如 何将其与我们所了解的事物相联系。"]

#1.将中文文本分词
data_new=[]
for sent in data:
data_new.append(" ".join(list(jieba.cut(sent)))) #使用jieba库的cut分词方法!!!
#2.调用fit_transform()方法
transfer=CountVectorizer(stop_words=["一种","哈哈"]) #禁用词--- 分词的时候不把他们当做特征词!!!
data_final=transfer.fit_transform(data_new)
print(f"特征名称:\n {transfer.get_feature_names_out()}")
print(f"data_new内容:\n{data_final.toarray()}")


TfidfVectorier类

1
2
3
4
5
6
1.TF-IDF思想:某个词/短语在一篇文章中出现概率高,并且在其他文章中很少出现,则认为有很好的区分度,适合用来分类
2.TF-IDF作用:用于评估对于一个文件/语料库文件的重要程度
3.TF-IDF公式:
TF(词频): 词语在文件中出现频率
IDF(逆向文档频率): log[总文件数目/文件数目]10
tfidf=TF*IDF

以中文段落为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
#准备数据
data=["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以 每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在 看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如 何将其与我们所了解的事物相联系。"]
#1.将中文文本分词
data_new=[]
for sent in data:
data_new.append(" ".join(list(jieba.cut(sent))))
#2.调用fit_transform()方法
transfer=TfidfVectorizer() #禁用词--- 分词的时候不把他们当做特征词!!!
data_final=transfer.fit_transform(data_new)
print(f"特征名称:\n {transfer.get_feature_names_out()}")
print(f"data_new内容:\n{data_final.toarray()}")


特征预处理(sklearn.preprocessing)

1
2
3
4
特征预处理:特征数据 --(转换函数)--> 特征数据[更加适合算法模型]	
特征预处理:
1.归一化(传统精确小数据场景): MinMaxScaler ----最大值最小值是变化并且容易受到异常点影响 ---> 鲁棒性较差
2.标准化(嘈杂大数据场景): StandardScaler ----

归一化(MinMaxScaler)

归一化推导公式:

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
from sklearn.preprocessing import MinMaxScaler #标准化
#1.获取数据
data=pd.read_csv("dating.txt") #文档在.py文件所在目录
data=data.iloc[:,:3]
print(data)
#2.实例化一个转换器类
transfer=MinMaxScaler(feature_range=[0,1]) #默认归一化在0-1
#3.调用fit_transform()
data_new=transfer.fit_transform(data)
print(data_new)

标准化(StandardScaler)

标准化推导公式:

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
from sklearn.preprocessing import StandardScaler #统一化
#1.获取数据
data=pd.read_csv("dating.txt") #文档在.py文件所在目录
print(data)
#2.实例化一个转换器类
transfer=StandardScaler()
#3.调用fit_transform()
data_new=transfer.fit_transform(data[['milage','Liters','Consumtime']])
print("标准化的结果:\n", data_new)
print("每一列特征的平均值:\n", transfer.mean_)
print("每一列特征的方差:\n", transfer.var_)


特征降维

1
2
3
4
5
6
7
8
9
10
11
12
13
14
概念:
在某些限定条件下,降低随机变量(特征)个数 ---> 一组“不相关”主变量

分类:
1.特征选择
1.1 嵌入式 Embeded
决策树
正则化
深度学习
1.2 过滤式 Filter
方差选择法:低方差特征过滤
相关系数:特征与特征之间的相关过程
1.3 包裹式
2.主成分分析

特征选择

低方差特征过滤(varianceThreshold)

1
2
3
4
5
6
1.删除低方差的一些特征,再结合方差的大小来考虑这个方式的角度
2. API:
sklearn.feature_selection.VarianceThreshold(threshold = 0.0) --删除所有低方差特征
Variance.fit_transform(X):
X是numpy array格式的数据[行,列]
返回值:删除训练集差异低于threshold的特征(默认是删除所有样本中具有相同值的特征)

筛选某些股票的指标特征

1
2
3
4
5
6
7
8
9
10
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
#1.获取数据
data=pd.read_csv("factor_returns.csv")
data=data.iloc[:,1:-2]
#2.实例化转换器类
transfer=VarianceThreshold(threshold=10) //特征方差选10
#3.调用fit_transform
data_new=transfer.fit_transform(data)
print(data_new)

相关系数过滤(scipy)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.皮尔逊相关系数:反映变量之间相关关系密切程度的统计指标
相关系数(r):-1到1之间
1.1 r>0表示正相关
1.2 r<0表示负相关
1.3 |r|=1表示两变量之间完全相关
1.4 r=0表示两变量之间无相关
1.5 0<|r|<1表示两变量存在一定程度相关,且越接近1之间的线性关系越密切,接近0之间表示线性相关越弱
1.6 |r|<0.4低度相关,0.4≤|r|<0.7显著性相关,0.7≤|r|<1高度线性相关

2. from scipy.stats import pearsonr
X: 特征值x,
Y: 特征值y,返回值是[特征值相关,特征值]

3.特征之间相关性很高:
3.1 选其中一个
3.2 加权求和 每个占比多少
3.3 主成分分析

主成分分析(PCA降维保留信息)

1
2
3
4
5
6
7
1.API:通过矩阵运算得到一个合适的直线->主成分分析的结果
sklearn.decomposition.PCA(n_components=None)
n_components:
小数:表示保留百分之多少的信息
整数:减少到多少特征
PCA.fit_transform(X是numpy array格式数据)
返回值:转换后指定维度的array

举例使用

1
2
3
4
5
6
7
8
9
from sklearn.decomposition import PCA
#1.获取数据
data=[[2,8,4,5],
[6,3,0,8],
[5,4,9,1]]
#2.实例化转换器类
transfer=PCA(n_components=2) #转换后有2个维度(2个特征)
data_new=transfer.fit_transform(data)
print(data_new)

instacart降维案例

问题分析

1
2
3
4
5
6
7
8
<探究用户对物品类别的喜好细分>
2.order_products_prior.csv订单与商品信息: order_id,product_id,add_to_cart_order,reordered
products.csv商品信息: product_id,product_name,aisle_id,department_id
orders.csv用户的订单信息: order_id,user_id,eval_set,order_number.....
aisles.csv商品所属物品类别: aisle_id,aisle
2. 得到四个csv文件 ----> 需要将user_id和aisle放在同一个表中
3. 找到user_id和aisle ----> 交叉表和透视表
4. 特征冗余过多 ---->PCA降维

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
from sklearn.decomposition import PCA
#1.获取数据(记得放在代码当前位置文件夹下)
data1=pd.read_csv("order_products__prior.csv")
data2=pd.read_csv("products.csv")
data3=pd.read_csv("orders.csv")
data4=pd.read_csv("aisles.csv")

#2.合并表 merge()函数
table1=pd.merge(data4,data2,on=["aisle_id","aisle_id"])
table2=pd.merge(table1,data1,on=["product_id","product_id"])
table3=pd.merge(table2,data3,on=["order_id","order_id"])

#3.交叉表 crosstab()函数
table=pd.crosstab(table3["user_id"],table3["aisle"])

#4.PCA降维 PCA()函数
transfer=PCA(n_components=0.95) #保留百分之95的数据
data_new=transfer.fit_transform(table) #降维
print(data_new) #输出PCA降维后的数据


sklearn转换器和估计器

1
2
3
4
5
6
7
8
9
 1.特征工程的步骤:
1.1 实例化(实例化的是一个转换器类(Transformer))
1.2 调用fit_transform(对于文档简历分类词频矩阵,不能同时调用)

2.转换器:特征工程的接口
2.1 转换器的形式:
2.1.1 fit_transform
2.1.2 fit
2.1.3 transform

转换器(fit_transform)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化

#特征预处理
##1.归一化(MinMaxScaler)
##2.标准化(StandardScaler)

std1=StandardScaler()
a=[[1,2,3],[4,5,6]]
print(std1.fit_transform(a))

std2=StandardScaler()
print(std2.fit(a))
print(std2.transform(a))

估计器(estimator)

1
2
3
4
5
6
7
8
9
 1.估计器的步骤:
1.1 实例化一个estimator
1.2 调用estimator.fit(x_train,y_train)计算 --> 调用完毕,模型生成
1.3 模型评估:
1.3.1 直接对比真实值和预测值:
y_predict=estimator.predict(x_test)
y_test==y_predict
1.3.2 计算准确率:
accuracy=estimator.score(x_test,y_test)

估计器的分类:

K-近邻算法(sklearn.neighbors.KNeighborsClassifier)

1
2
3
4
5
1.核心思想: 你的"邻居"来推断你的类别
2.距离公式: 欧式距离 / 明可夫斯基距离
3.API: sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
3.1 n_neighbors: (默认整数类型为5) -->通过k_neighbors查询默认使用的邻居数
3.2 algorithm: 可选用于计算最近邻居的算法[auto/ball_tree/kd_tree/brute]

模型选择与调优(sklearn.model_selection.GridSearchCV)

1
2
3
4
5
6
7
8
9
10
11
12
1.交叉验证(cross validation):为了让被评估的模型更加准确可信
1.1将拿到的训练数据更加细化:
训练集:训练集+验证集
测试集:测试集
2.超参数搜索-网格搜索(Grid Search):
2.1 超参数:有很多参数是需要手动指定的(如k-近邻算法中的K值)
2.2 API: sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)
2.2.1 estimator:估计器对象
2.2.2 param_grid:估计器参数(dict) --> 一般是取字典{"n_neighbors":[1,3,5]}
2.2.3 cv:指定几折交叉验证(训练集中训练集和验证集的划分有几次,然后得出平均值)
2.2.4 fit():输入训练数据
2.2.5 score():准确率

电影类型分析

鸢尾花分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
#用KNN算法对鸢尾花进行分类
#1.获取数据
iris=load_iris()

#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=6)

#3.特征工程(标准化)
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.transform(x_test)

#4.KNN算法预估器
estimator=KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)

#5.模型评估
##方法一:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print(y_test==y_predict)
##方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:",score)

鸢尾花分析(添加网格搜索和交叉验证)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
#用KNN算法对鸢尾花进行分类
#1.获取数据
iris=load_iris()

#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=6)

#3.特征工程(标准化)
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.transform(x_test)

#4.KNN算法预估器
estimator=KNeighborsClassifier()

##加入网格搜索和交叉验证
param_dict={"n_neighbors":[1,3,5,7,9,11]}
estimator=GridSearchCV(estimator,param_grid=param_dict,cv=10)

estimator.fit(x_train,y_train)

#5.模型评估
##方法一:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print(y_test==y_predict)
##方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:",score)

#6.获取结果分析
print("最佳参数:",estimator.best_params_)
print("最佳结果:",estimator.best_score_)
print("最佳估计器:",estimator.best_estimator_)
print("交叉验证的结果:",estimator.cv_results_)

预测facebook签到位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
#Facebook预测签到位置

##1.获取数据
data=pd.read_csv("train.csv")

##2.数据处理(获取特征值和目标值)
###2.1 缩小数据范围 2<x<2.5 1.0<y<1.5
###2.2 改变time时间 年月日时分秒
###2.3 过滤签到次数少的地点
data=data.query("x<2.5&x>2&y>1.0&y<1.5")
time_value=pd.to_datetime(data["time"],unit="s")
data=pd.DatetimeIndex(time_value)

place_count=data.groupby("place_id")
data_final=data[data["place_id"].isin(place_count[place_count>3].index.values)]
##3.特征工程
x=data_final[["x","y","accuracy","day","weekday","hour"]]
y=data_final["place_id"]
x_train,x_test,y_train,y_test=train_test_split(x,y)

##4.KNN算法预估器
estimator=KNeighborsClassifier()

###加入网格搜索和交叉验证
param_dict={"n_neighbors":[1,3,5,7,9,11]}
estimator=GridSearchCV(estimator,param_grid=param_dict,cv=10)

estimator.fit(x_train,y_train)

##5.模型评估
###方法一:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print(y_test==y_predict)
###方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:",score)

##6.获取结果分析
print("最佳参数:",estimator.best_params_)
print("最佳结果:",estimator.best_score_)
print("最佳估计器:",estimator.best_estimator_)
print("交叉验证的结果:",estimator.cv_results_)

朴素贝叶斯算法(sklearn.naive_bayes.MultinomialNB(alpha=1.0))

条件概率与联合概率

贝叶斯公式

拉普拉斯平滑系数(防止计算出的分类概率为0)

文本分类分析(新闻分类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.naive_bayes import MultinomialNB
from sklearn.datasets import fetch_20newsgroups #引入新闻数据集
from sklearn.feature_extraction.text import TfidfVectorizer #文本提取的库
#1.获取数据
news=fetch_20newsgroups(subset="all")
#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(news.data,news.target)
#3.特征工程
transfer=TfidfVectorizer()
##3.1文本特征提取
x_train=transfer.fit_transform(x_train)
x_test=transfer.transform(x_test)
#4.朴素贝叶斯预估器流程
estimator=MultinomialNB()
estimator.fit(x_train,y_train)
#5.模型评估
##方法一:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print(y_test==y_predict)
##方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:",score)

决策树(sklearn.tree.DecisionTreeClassifier)

信息论基础

1
2
3
4
5
6
1.信息:
香农:消除随机不定性的东西
例:小明 年龄未知 "我今年18岁了" (我可以通过说的这句话推断出年龄,消除了不知道的年龄)--就是信息
小华 "小明明年19岁" (因为小明的话已经推断出年龄,所以这句话不算消除) --不是信息
2.信息的衡量(信息商/信息熵)
3.信息增益[g(D,A)]=信息熵[H(D)]-条件熵[H(D|A)]

决策树划分依据(3种)

1
2
3
1. ID3  信息增益(最大的准则)
2. C4.5 信息增益比(最大的准则)
3. CART 分类树:基尼系数(最小的准则) 在sklearn中可以选择划分的默认原则

决策树的实现

1
2
3
4
5
sklearn.tree.DecisionTreeClassifier(criterion='gini',max_depth=None,random_state=None)
1.决策树分类器
2.criterion: 默认是gini系数(也可以选择信息增益的熵entropy)
3.2.
4.random_state: 随机数种子

鸢尾花预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer #文本提取的库
from sklearn.tree import DecisionTreeClassifier #决策树
from sklearn.datasets import load_iris #传入鸢尾花数据集
#1.获取数据
iris=load_iris()
#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=22)
#4.决策树预估器流程
estimator=DecisionTreeClassifier(criterion='entropy') #设置为数据增益
estimator.fit(x_train,y_train)
#5.模型评估
##方法一:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print(y_test==y_predict)
##方法二:计算准确率
score=estimator.score(x_test,y_test)
print("准确率为:",score)

决策树可视化(sklearn.tree.export_graphviz()导出DOT格式)

1
2
3
4
5
6
7
sklearn.tree.export_graphviz()该函数能够导出DOT格式
1.决策树可视化
2.estimator: 预估器对象
3.out_file: 输出名称
4.feature_names:特征的名字

得到dot文件之后复制内容去http://webgraphviz.com/执行

泰坦尼克号乘客生存预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler #引入特征预处理中的标准化
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer #缺失值处理
from sklearn.feature_extraction.text import TfidfVectorizer #文本提取的库
from sklearn.tree import DecisionTreeClassifier #决策树
from sklearn.tree import export_graphviz #决策树可视化
#1.获取数据
titanic=pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
##1.1数据处理
x=titanic[['pclass','age','sex']]
y=titanic['survived']
##1.2缺失值处理(将特征当中有类别的特征进行字典特征抽取)
x['age'].fillna(x['age'].mean(),inplace=True)
dict=DictVectorizer(sparse=False)
x=dict.fit_transform(x.to_dict(orient="records"))
#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
#3.决策树预估器流程
estimator=DecisionTreeClassifier(max_depth=5) #设置为数据增益
estimator.fit(x_train,y_train)
#4.模型评估
score=estimator.score(x_test,y_test)
print("准确率为:",score)

随机森林(sklearn.ensemble.RandomForestClassifier)

1
2
3
4
5
6
7
8
9
10
11
12
13
1.随机森林: 一个包含多个决策树的分类器(输出的类型是通过个别树输出的类别的众数决定)
2.随机:
2.1 训练集随机: bootstrap随机有放回抽样
2.2 特征随机: 从M个特征中随机抽取m个特征(很像降维)

3.API: sklearn.ensemble.RandomForestClassifier
3.1 随机森林分类器
3.2 n_estimators: 几个估计器
3.3 criterion: 默认gini系数,(也可以使用信息增益的熵entropy)
3.4 max_depth: 树的深度
3.5 bootstrap: 是否设置随机有放回抽样
3.6 random_state:
3.7 min_samples_split:

回归问题

线性回归

线性回归定义

1
2
3
4
5
6
7
8
9
1.基本概念:通过回归方程(函数)对一个/多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式
2.线性模型(回归方程):特征值和目标值之间建立一个关系
3.线性模型分类:
3.1 线性关系
3.1.1 直线关系: 单特征与目标值的关系
3.1.2 平面关系: 两个特征与目标值的关系
3.2 非线性关系
3.2.1 自变量一次: y=ax1+bx2+cx3+....+b (最多是x的一次方)
3.2.2 参数一次: y=ax1+bx2^2+cx3^3+...+b (a1/b/c等等都是一次)

线性回归通用公式:

最小二乘法(损失函数)

最小二乘法公式:

优化方法之正规方程(直接求解sklearn.linear_model.LinearRegression)

1
2
3
4
 sklearn.linear_model.LinearRegression(fit_intercept=True)
1.fit_intercept: 是否计算偏置
2.LinearRegression.coef_: 回归系数
3.LinearRegression.intercept_: 偏置

优化方法之梯度下降(不断试错sklearn.linear_model.SGDRegressor)

1
2
3
4
5
6
7
8
9
10
 sklearn.linear_model.SGDRegressor(loss="squared_loss",fit_intercept=True,learing_rate='invscaling',eta0=0.01)
1.SGDRegressor类实现了随机梯度下降学习(支持不同的loss函数和正则化惩罚项来拟合线性回归模型)
2.loss: 默认是普通最小二乘法squared_loss
3.fit_intercept: 是否计算偏置
4.learing_rate: 学习率填充
4.1 constant(常数值的学习率): eta=eta0
4.2 optimal(默认): eta=1.0/(alpha=*(t+t0))
4.3 invscaling: eta=eta0/pow(t,power_t) [power_t=0.25存在父类当中]
4.4 SGDRegressor.coef_: 回归系数
4.5 SGDRegressor.intercept_: 偏置

波士顿房价预测(正规方程和梯度下降对比)

正则方程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston #导入波士顿数据集
from sklearn.model_selection import train_test_split #划分数据集
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
#1.获取数据集
boston=load_boston()
#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(boston.data,boston.target,random_state=22)
#3.标准化
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train) #训练集
x_test=transfer.transform(x_test) #测试集
#4.决策树预估器流程
estimator=LinearRegression()
estimator.fit(x_train,y_train)
##得出模型
print("权重系数为:",estimator.coef_)
print("偏置为:",estimator.intercept_)

梯度下降

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston #导入波士顿数据集
from sklearn.model_selection import train_test_split #划分数据集
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model.stochastic_gradient import SGDRegressor
#1.获取数据集
boston=load_boston()
#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(boston.data,boston.target,random_state=22)
#3.标准化
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train) #训练集
x_test=transfer.transform(x_test) #测试集
#4.决策树预估器流程
estimator=SGDRegressor()
estimator.fit(x_train,y_train)
##得出模型
print("权重系数为:",estimator.coef_)
print("偏置为:",estimator.intercept_)

两者对比

回归性能评估(sklearn.metrics.mean_squared_error)

回归性能评估公式:

1
2
3
4
5
6
7
8
9
10
11
12
	1.API: sklearn.metrics.mean_squared_error(y_true,y_pred)
1.1 均方误差回归损失
1.2 y_true: 真实值
1.3 y_pred: 预测值

#在之前的基础上:
from sklearn.metrics import mean_squared_error
#5.模型评估
y_predict=estimator.predict(x_test)
print("预测房价:",y_predict)
error=mean_squared_error(y_test,y_predict)
print("梯度下降的-均方误差为:",error)

刚才的波士顿房价上进行预测:

梯度下降优化方法(GD/SGD/SAG)

1
2
3
4
5
1.GD(原始的):计算所有样本的值才能够得到梯度(计算量大)

2.SGD(随机梯度下降):一次迭代只考虑一个训练样本

3.SAG(随机平均梯度法):提高收敛速度(SGDRegressor和岭回归以及逻辑回归中都会有SAG优化)

欠拟合与过拟合()

1
2
3
4
5
6
7
8
 训练集很合理,测试集不行
1.欠拟合:一个假设在训练数据上不能够获得比其他假设更好的拟合,测试集上不能很好拟合(学的特征太少)
1.1 原因:学习的特征过少
1.2 解决方法:增加数据的特征数量

2.过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合,测试集上不能很好拟合(学的特征太多)
2.1 原因:原始特征过多,存在一些嘈杂特征,模型过于复杂
2.2 解决方法:正则化

正则化

1
2
3
1. L1正则化:可以使得其中一些w的值直接为0,删除这个特征的影响  (LASSO回归)

2. L2正则化:可以使得其中一些w都很小,都接近0,削弱某个特征的影响 (Ridge回归)

岭回归(带L2正则化的线性回归)

1
2
3
4
5
6
1.API: sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True,solver="auto",normalize=False)
1.1 alpha: 正则化力度 (0-1 1-10)
1.2 solver: 会根据数据自动选择优化方法(如果数据集和特征都较大会使用SAG随机平均梯度法)
1.3 normalize: 数据是否进行标准化
1.4 Ridge.coef_: 回归权重
1.5 Ridge.intercept_: 回归偏置

波士顿房价预测(岭回归Ridge)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston #导入波士顿数据集
from sklearn.model_selection import train_test_split #划分数据集
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge
#1.获取数据集
boston=load_boston()
#2.划分数据集
x_train,x_test,y_train,y_test=train_test_split(boston.data,boston.target,random_state=22)
#3.标准化
transfer=StandardScaler()
x_train=transfer.fit_transform(x_train) #训练集
x_test=transfer.transform(x_test) #测试集
#4.决策树预估器流程
estimator=Ridge()
estimator.fit(x_train,y_train)
##得出模型
print("权重系数为:",estimator.coef_)
print("偏置为:",estimator.intercept_)

分类算法

逻辑回归

逻辑回归概念

sigmoid函数

逻辑回归过程

流程:

逻辑回归损失(对数似然损失)

对数似然损失:

综合完整损失函数:

逻辑回归损失优化(梯度下降)

1
减少损失函数的值 --> 更新逻辑回归前面对应算法的权重参数 --> 提升原本属于1类别的概率,降低原本属于0类别的概率

逻辑回归API(sklearn.linear_model.LogisticRegression)

1
2
3
4
1. sklearn.linear_model.LogisticRegression(solver='liblinear',penalty='l2',c=1.0)
1.1 solver: 优化求解方式(默认开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数)
1.2 penalty: 正则化的种类(l1和l2(默认))
1.3 c: 正则化力度

癌症分类

数据描述:

1
2
3
4
5
6
7
8
9
10
11
12
1.原始数据:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/
2.数据分析:
2.1 一共699条样本,共11列数据(第一列id,后9列分别是与肿瘤相关的医学特征,最后一列表示肿瘤类型的数值)
2.2 包含16个缺失值(用?标出)

3.流程分析:
3.1 获取数据(读取时加上names)
3.2 数据处理(处理缺失值)
3.3 数据集划分
3.4 特征工程(无量纲化处理-标准化)
3.5 逻辑回归预估器
3.6 模型评估

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
#3.1 获取数据(读取时加上names)
path="https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']
data=pd.read_csv(path,names=column_name)
print(data)
#3.2 数据处理(处理缺失值)
data=data.replace(to_replace='?',value=np.nan) #将所有缺失值用NaN替换?
data=data.dropna() #删掉所有NaN值
#3.3 数据集划分
x=data[column_name[1:10]]
y=data[column_name[10]]
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
#3.4 特征工程(无量纲化处理-标准化)
std=StandardScaler()
x_train=std.fit_transform(x_train)
x_test=std.transform(x_test)
#3.5 逻辑回归预估器
lr=LogisticRegression()
lr.fit(x_train,y_train)
#3.6 模型评估
print("得出来的权重:",lr.coef_)
print("预测的类别:",lr.predict(x_test))
print("预测的准确率:",lr.score(x_test,y_test))

分类的评估方法(sklearn.metrics.classification_report)

混淆矩阵

混淆矩阵:

精确率(Precision)与召回率(Recall)

精确率:

召回率:

F1-score

分类评估预测API

1
2
3
4
5
6
1.sklearn.metrics.classification_report(y_true,y_pred,labels=[],target_names=None)
1.1 y_true: 真实目标值
1.2 y_pred: 估计器预测目标值
1.3 labels: 指定类别对应的数字
1.4 target_names: 目标类别名称
1.5 return: 每个类别精准率与召回率

上面基础上加入分类评估

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
#3.1 获取数据(读取时加上names)
path="https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']
data=pd.read_csv(path,names=column_name)
#3.2 数据处理(处理缺失值)
data=data.replace(to_replace='?',value=np.nan)
data=data.dropna()
#3.3 数据集划分
x=data[column_name[1:10]]
y=data[column_name[10]]
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
#3.4 特征工程(无量纲化处理-标准化)
std=StandardScaler()
x_train=std.fit_transform(x_train)
x_test=std.transform(x_test)
#3.5 逻辑回归预估器
lr=LogisticRegression()
lr.fit(x_train,y_train)
print("得出来的权重:",lr.coef_)
print("预测的类别:",lr.predict(x_test))
print("预测的准确率:",lr.score(x_test,y_test))

#3.6 模型评估
print("精确率和召回率为:",classification_report(y_test,lr.predict(x_test),labels=[2,4],target_names=['良性','恶性']))

TPR和FPR

ROC曲线

通过FPR和TPR来构成:

AUC指标(sklearn.metrics.roc_auc_score)

1
2
3
4
5
6
7
8
1.AUC的概率意义: 随机取一对正负样本,正样本得分>负样本的概率
2.AUC取值范围: 0.5-1(取值越高越好,说明TPR高)
2.1 0.5<AUC<1: 优于随机猜测
2.2 AUC=1:完美分类器(不管怎么设定阈值都能完美预测)
3.API: sklearn.metrics.roc_auc_score(y_true,y_score)
3.1 计算ROC曲线面积(AUC值)
3.2 y_true: 每个样本的真实类别(必须为0/1)
3.3 y_score: 每个样本预测的概率值

上面基础上加入auc指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.metrics import roc_auc_score
#3.1 获取数据(读取时加上names)
path="https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']
data=pd.read_csv(path,names=column_name)
#3.2 数据处理(处理缺失值)
data=data.replace(to_replace='?',value=np.nan)
data=data.dropna()
#3.3 数据集划分
x=data[column_name[1:10]]
y=data[column_name[10]]
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
#3.4 特征工程(无量纲化处理-标准化)
std=StandardScaler()
x_train=std.fit_transform(x_train)
x_test=std.transform(x_test)
#3.5 逻辑回归预估器
lr=LogisticRegression()
lr.fit(x_train,y_train)
print("得出来的权重:",lr.coef_)
print("预测的类别:",lr.predict(x_test))
print("预测的准确率:",lr.score(x_test,y_test))

#3.6 模型评估
print("精确率和召回率为:",classification_report(y_test,lr.predict(x_test),labels=[2,4],target_names=['良性','恶性']))
y_test=np.where(y_test>2.5,1,0) #将2和4转换为0和1用于auc的参数
print("auc",roc_auc_score(y_test,lr.predict(x_test)))

模型保存和加载(sklearn.externals.joblib)

sklearn模型API

1
2
3
1.sklearn.externals.joblib
1.1 保存: joblib.dump(estimator,'test.pkl') #后缀为pkl文件
1.2 加载: estimator=joblib.load('test.pkl')

无监督学习

1
2
1.聚类: K-means算法(K均值聚类)
2.降维: PCA

K-means算法(sklearn.cluster.KMeans)

四步骤示意图

1
2
3
4
1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
4、如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行第二步过程

K-means算法API

1
2
3
4
5
1.API: sklearn.cluster.KMeans(n_clusters=8,init='k-means++')
1.1 k-means聚类
1.2 n_clusters: 开始聚类中心的数量(几个堆)
1.3 init: 初始方法
1.4 labels_:默认标记的类型(可以和真实值比较)

对Instacart Market用户聚类

1
2
3
4
5
6
	1.降维后的数据
2.k-means聚类
3.聚类结果显示
km=KMeans(n_clusters=4)
km.fit(data)
pre=km.predict(data)

Kmeans性能评估指标(sklearn.metrics.silhouette_score)

轮廓系数

1
2
3
4
1.很像高级语言程序里面的"高内聚低耦合"
2.轮廓系数介于[-1,1]
3.b_i >> a_i : 轮廓系数趋近于1 效果很好
4.b_i << a_i : 轮廓系数趋近于-1 效果不好

轮廓系数API

1
2
3
4
sklearn.metrics.silhouette_score(X,labels)
1.计算所有样本的平均轮廓系数
2.X:特征值
3.labels:被聚类标记的目标值

python

初识python

1
2

python安装以及环境配置参考https://www.bilibili.com/video/BV1wD4y1o7AS?p=3&spm_id_from=pageDriver

第一个输出

1
2
3
4
1.文件-新建-新建项目
2.选择项目右键新建-文件名为first.py
3.书写print("hello world");
4.点击空白位置右键run first


输出(print)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#输出数字
print(520);
print(98.5);

#输出字符串
print("123s");
print('123as');

#输出含有运算符的表达式
print(3+1); #输出4

#输出到文件中
fp=open('D:/test.txt','a+'); #输出到d盘下面
print('helloworld',file=fp); #输出内容为 helloworld
fp.close();

#不进行换行输出(输出内容在一行) --用逗号隔开
print('hello','world','Python');

输出其他内容

输出到文件里面


转义字符和原字符(r/R+字符串)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

print('--1.转行(分行)-------------');
print('hello\nworld');

print('--2.制表(四个字符为一个)-------------');
print('hello\tworld');
print('helloooo\tworld'); #四个字符是一个\t

print('--3.回车功能(覆盖符号之前的所有内容)---');
print('hello\rworld'); #hello输入之后回车world会把hello挤掉

print('--4.退一个格功能--------------');
print('hello\bworld');

print('--5.将字符串里面的单引号不被识别为转义字符---------------------------');
print('老师说:\'给我考满分\'');

print('--不希望转义字符起作用,使用原字符(字符串前面加r/R)------');
print(r'hello\nworld');
print(r'hello\nworld\\'); #注意:最后两个是\\ √
print(r'hello\nworld\'); #注意:最后一个字符不能是\ ×


标识符和保留字

1
类似于java和c语言

后续

1
2

俺买了python从入门到实践,看书去了!

B册编程题

第1章 认识c语言

1.1 计算长方形面积和周长

具体代码

1
2
3
4
5
6
7
8
9
10
11
12

#include <stdio.h>
int main(){
double x,y;
double c,s;
scanf("%lf,%lf",&x,&y); //逗号隔开输入长x和宽y
c=2*x+2*y; //周长
s=x*y; //面积
printf("周长是%.5f\n",c);
printf("面积是%.5f\n",s);
return 0;
}

执行结果


1.2 计算两者取余(%)和整除(/)

具体代码

1
2
3
4
5
6
7
8
9

#include <stdio.h>
int main(){
int a,b;
scanf("%d %d",&a,&b); //题目要求输入两个整数
printf("整除结果是%d\n",a/b); //因为都是整数 所以结果也是整数
printf("取余结果是%d\n",a%b); //因为都是整数 所以结果也是整数
return 0;
}

执行结果


1.3 分割浮点数的整数和小数部分

具体代码

1
2
3
4
5
6
7
8
9
10
11
12

#include <stdio.h>
int main(){
double a;
double xiao=0;
scanf("%lf",&a); //输入一个浮点数a
int n=(int)(a); //强转为int就是整数部分
xiao=a-n; //然后用原始数据-整数部分
printf("整数部分是%d\n",n);
printf("小数部分是%f\n",xiao);
return 0;
}

执行结果


1.4 大小写互换

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13

#include <stdio.h>
int main(){
char n;
char n1;
scanf("%c",&n);
n1=n-32; //小写转大写需要减少32
printf("大写对应的ASCII码为:%d\n",n1);
printf("小写对应的ASCII码为:%d\n",n);
printf("大写的字符为:%c\n",n1);
printf("小写的字符为:%c\n",n);
return 0;
}

执行结果


1.5 华室温度转摄氏温度

具体代码

1
2
3
4
5
6
7
8
9
10

#include <stdio.h>
int main(){
double hua; //华氏温度
double she; //摄氏温度
scanf("%lf",&hua); //输入华氏温度
she=5*(hua-32)/9.0; //公式
printf("%f",she); //使用默认格式长度输出
return 0;
}

执行结果


第2章 顺序结构

2.1 输入圆半径,得到半径相关数据

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <stdio.h>
#define PI 3.1415926
int main(){
double r;
double zc,mj,tj;
scanf("%lf",&r); //输入格式lf 老忘记
printf("输入的圆的半径为%.3f\n",r);
zc=2*PI*r; //周长是2*πr
mj=PI*r*r; //面积是π*r*r
tj=(PI*r*r*r*4)/3; //体积是三分之四的π*r*r*r
printf("原的周长是:%.3f\n",zc);
printf("原的面积是:%.3f\n",mj);
printf("原的体积是:%.3f\n",tj);
return 0;
}

执行结果


2.2 成绩信息统计

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <stdio.h>
int main(){
double c1,c2,c3,c4; //四门课
double ag; //四门课平均值
//题目要求输入四门课成绩
printf("请输入四门课成绩,并间隔逗号:\n");
scanf("%lf,%lf,%lf,%lf",&c1,&c2,&c3,&c4);
ag=(c1+c2+c3+c4)/4; //计算平均值
printf("第一门课成绩c1为:%.2f\n",c1);
printf("第二门课成绩c2为:%.2f\n",c2);
printf("第三门课成绩c3为:%.2f\n",c3);
printf("第四门课成绩c4为:%.2f\n",c4);
printf("平均值为%.2f",ag); //题目要求保留两位小数
return 0;
}

执行结果


c语言课本题目

第一章 初识c语言

例1.1 屏幕输出一行信息

具体代码

1
2
3
4
5
6

#include <stdio.h>
int main(){
printf("hello world");
return 0;
}

执行结果


例1.2 求两个整数之和

具体代码

1
2
3
4
5
6
7
8
9
10

#include <stdio.h>
int main(){
int a,b,sum;
a=123;
b=456;
sum=a+b;
printf("sum 之和是:%d\n",sum);
return 0;
}

执行结果


例1.3 求最大值

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

#include <stdio.h>
int main(){
int a,b,sum;
int da(int a,int b); //一定要定义方法 而且里面要有数据类型
scanf("%d,%d",&a,&b); ///scanf输入
sum=da(a,b); //调用方法返回max给sum
printf("两个之中最大的是:%d\n",sum);
return 0;
}

int da(int a,int b){
int max; //存储最后的最大值
if(a>b){
max=a; //a大
}else{
max=b; //b大
}
return max;
}

执行结果


习题5 输出*****图形

具体代码

1
2
3
4
5
6
7
8
9

#include <stdio.h>
int main(){
printf("*****\n");
printf(" *****\n");
printf(" *****\n");
printf(" *****\n");
return 0;
}

执行结果


第二章 算法

例2.1 求1到5乘积

具体代码

1
2
3
4
5
6
7
8
9
10

#include <stdio.h>
int main(){
int sum=1;
for(int i=1;i<=5;i++){ //循环乘1*2*3*4*5
sum*=i;
}
printf("%d",sum); //输出结果
return 0;
}

执行结果


例2.3 判断闰年

具体代码

1
2
3
4
5
6
7
8
9
10

#include <stdio.h>
int main(){
for(int i=2000;i<=2500;i++){
if(i%400==0||(i%4==0&&i%100!=0)){ //符合条件输出
printf("%d ",i);
}
}
return 0;
}

执行结果


例2.4 求1-(1/2)+(1/3)-(1/4)到-(1/100)

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
int main(){
double sum=0; //得到最后结果
double temp=0; //获取每次的值
for(int i=1;i<=100;i++){ //相加100次
temp=1.0/i; //一定是1.0 不然就是整除为0了
if(i%2==0){
temp=temp*(-1); //奇数都是负的
}
sum+=temp; //每次相加
}
printf("%.10f",sum); //输出小数点后10位
return 0;
}

执行结果


例2.5 判断素数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include <stdio.h>
int main(){
int n;
scanf("%d",&n); //输入一个整数
if(n>=3){
for(int i=2;i<n;i++){ //从2开始依次
if(n%i!=0){ //如果不能被整除就不是素数
printf("%d",n);
break;
}else{
break; //如果可以被整除那就不是
}
}

}
else{
printf("输入的数字不比3大,输入错误请重新输入!");
}

return 0;
}

执行结果


第三章 顺序程序设计

例3.1 温度转换

具体代码

1
2
3
4
5
6
7
8
9
10

#include <stdio.h>
int main(){
double n; //华氏法
double res; //转换结果
scanf("%lf",&n); //一定是lf
res=5.0*(n-32)/9; //转化公式
printf("%f\n",res); //输出结果
return 0;
}

执行结果


例3.3 大小写转换

具体代码

1
2
3
4
5
6
7
8

#include <stdio.h>
int main(){
char a;
a='A'; //赋值
a=a+32; //大写+32=小写
printf("%c\n",a);
}

执行结果


例3.4 求三角形面积(海伦公式)

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
#include <Math.h> //后面要用sqrt开根号的函数
int main(){
double a; //边1
double b; //边2
double c; //边3
double s; //海伦公式里面的s
double res; //获取最终结果
scanf("%lf,%lf,%lf",&a,&b,&c); //输入三边
s=(a+b+c)/2;
res=sqrt(s*(s-a)*(s-b)*(s-c)); //海伦公式
printf("%.5f",res);
return 0;
}

执行结果


例3.5 求一元二次方程的根

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#include <stdio.h>
#include <Math.h>
int main(){
int a; //x2的系数
int b; //x的系数
int c; //常数的系数
double temp;
double res1;
double res2;
scanf("%d,%d,%d",&a,&b,&c); //输入一定要用逗号隔开
temp=b*b-4*a*c;
res1=(-b+sqrt(temp))/(2.0*a);
res2=(-b-sqrt(temp))/(2.0*a);
printf("%7.2f",res1);
printf("%7.2f",res2);
return 0;
}

执行结果


例3.9 输入三个字符,然后putchar输出

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
#include <Math.h>
int main(){
char a='B';
char b='O';
char c='Y';
printf("输入新的之前%c%c%c\n",a,b,c);
scanf("%c",&a);
printf("输入新的之后");
putchar(a); //putchar输出单个字符
putchar(b);
putchar(c);
return 0;
}

执行结果


例3.10 输入大写字母输出小写

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
#include <Math.h>
int main(){
char a='B';
char b='O';
char c='Y';
printf("输入新的之前%c%c%c\n",a,b,c);
scanf("%c",&a);
printf("输入新的之后");
putchar(a); //putchar输出单个字符
putchar(b);
putchar(c);
return 0;
}

执行结果


习题3.4 输入不同类型的c1和c2字符

1.输入字符类型范围内c1和c2

具体代码

1
2
3
4
5
6
7
8
9
10
11

#include <stdio.h>
#include <Math.h>
int main(){
char c1,c2;
c1=97; //char范围是-127到128
c2=98;
printf("c1=%c,c2=%c\n",c1,c2);
printf("c1=%d,c2=%d\n",c1,c2);
return 0;
}

执行结果

2.输入字符类型范围外c1和c2

具体代码

1
2
3
4
5
6
7
8
9
10
11

#include <stdio.h>
#include <Math.h>
int main(){
char c1,c2;
c1=197; //char范围是-127到128 所以输入的是范围外
c2=198;
printf("c1=%c,c2=%c\n",c1,c2);
printf("c1=%d,c2=%d\n",c1,c2);
return 0;
}

执行结果

3.输入整数类型范围内c1和c2

具体代码

1
2
3
4
5
6
7
8
9
10
11

#include <stdio.h>
#include <Math.h>
int main(){
int c1,c2; //整数类型c1和c2
c1=97;
c2=98;
printf("c1=%c,c2=%c\n",c1,c2); //整数类型赋给字符类型 可能存在截取
printf("c1=%d,c2=%d\n",c1,c2); //本来输入的就是int类型 所以就输出原样
return 0;
}

执行结果


习题3.5 多种类型输入和输出

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
#include <Math.h>
int main(){
int a,b;
float x,y;
char c1,c2;
scanf("a=%db=%d",&a,&b);
scanf("%f%e",&x,&y);
scanf("%c%c",&c1,&c2);
printf("a=%d,b=%d",a,b);
printf("x=%f,y=%e",x,y);
printf("a=%c,b=%c",c1,c2);
return 0;
}

执行结果


习题3.6 China译成密码

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#include <stdio.h>
int main(){
char c1,c2,c3,c4,c5; //定义五个字符
c1='C'; //给五个字符赋初值
c2='h';
c3='i';
c4='n';
c5='a';
c1=c1+4; //直接加4就行
c2=c2+4;
c3=c3+4;
c4=c4+4;
c5=c5+4;
putchar(c1); //使用输出单个字符函数输出
putchar(c2);
putchar(c3);
putchar(c4);
putchar(c5);
printf("\n");
printf("%c",c1); //使用printf输出
printf("%c",c2);
printf("%c",c3);
printf("%c",c4);
printf("%c",c5);
return 0;
}

执行结果


第4章 选择结构程序设计

例4.2 输入两个数排序

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#include <stdio.h>
int main(){
double a,b; //要排序的a和b
double t; //中间变量
scanf("%lf,%lf",&a,&b);
if(a<b){ //两个数交换 一定要有个中间变量t
t=a;
a=b;
b=t;
}
printf("最大的是%.5f,最小的是%.5f\n",a,b);
return 0;
}

执行结果


例4.3 输入三个数排序

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include <stdio.h>
int main(){
double a,b,c; //要排序的三个数
double t; //中间变量
scanf("%lf,%lf,%lf",&a,&b,&c); //double要用lf输入
if(a>b){ //b小 放前面
t=a;
a=b;
b=t;
}
if(a>c){ //说明a<b 如果c小 交换a和c
t=a;
a=c;
c=t;
}
if(b>c){ //前面都不符合说明a是最小的 要比较b和c
t=b;
b=c;
c=t;
}
printf("%.5f,%.5f,%.5f\n",a,b,c);
return 0;
}

执行结果


例4.4 大小写转换

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13

#include <stdio.h>
int main(){
char a;
scanf("%c",&a); //a=getchar();
if(a>='A'&&a<='Z'){ //大写转小写
a=a+32;
}else{ //小写不用转换

}
printf("%c\n",a);
return 0;
}

执行结果


例4.5 分段函数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

//1.简单的if语句
#include <stdio.h>
int main(){
int x,y; //
scanf("%d",&x); //输入x 对应输出y
if(x<0){
y=-1;
}
if(x=0){
y=0;
}
if(x>0){
y=1;
}
printf("%d",y); //输出对应y
return 0;
}

执行结果


例4.6 按照等级输出成绩

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>
int main(){
char grade;
scanf("%c",&grade); //输入分数
switch(grade)
{
case 'A':printf("85-100分\n");break;
case 'B':printf("70-84分\n");break;
case 'C':printf("60-69分\n");break;
case 'D':printf("<60分\n");break;
default:printf("重新输入成绩等级!");
}
return 0;
}

执行结果


例4.7 switch语句处理菜单命令

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#include <stdio.h>
int main(){
void action1(int a,int b); //声明两个函数
void action2(int a,int b);
char ch; //要判断的字符
int a=15;
int b=23;
ch=getchar(); //输入一个字符
switch(ch)
{
case 'A':
case 'a':action1(a,b);break; //A和a同时跳转action1方法
case 'B':
case 'b':action2(a,b);break; //B和b同时跳转action1方法
default:printf("不符合题意,重新登陆!");
}
return 0;
}

void action1(int a,int b){
printf("执行action1方法之后结果是%d\n",a+b); //加法
}

void action2(int a,int b){
printf("执行action2方法之后结果是%d\n",a*b); //乘法
}

执行结果


习题4.4 输出三个数最大数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

#include <stdio.h>
int main(){
int a,b,c;
int t; //作为中间值
scanf("%d,%d,%d",&a,&b,&c); //输入三个整数
if(a>b){ //a大 往后放
t=a;
a=b;
b=t;
}
if(a>c){ //a<b 看看a和c的大小
//a大 往后放 这样的话就是 c<a<b
t=a;
a=c;
c=t;
}
if(b>c){ //a<b a<c 但是b和c的大小要排序
//b>c>a 要把b和c换一下
t=b;
b=c;
c=t;
}
printf("三个数中最大的是:%d",c);
return 0;
}

执行结果


习题4.5 输出平方根

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#include <stdio.h>
#include <math.h> //使用sqrt函数
int main(){
int a;
int res;
scanf("%d",&a); //输入一个<1000的正数
if(a>=1000){
printf("输入有误,请重新输入!!!");
}
res=(int)sqrt(a); //强转为int 这样输出整数部分
printf("平方根为:%d",res);
return 0;
}

执行结果


习题4.5 分段函数输出y值

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <stdio.h>
int main(){
int x,y;
scanf("%d",&x); //输入整数x
if(x<1){
y=x;
}else if(x>=1&&x<10){
y=2*x-1;
}else if(x>=10){
y=3*x-11;
}
printf("输入的x值是:%d\n",x);
printf("对应的y值是:%d",y);
return 0;
}

执行结果


习题4.9 拆每位数字

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <stdio.h>
int main(){
int x;
scanf("%d",&x); //输入一个整数
int n=0;
int ge=0; //统计多少位
while(x!=0){ //每一位都拆完就结束
n=x%10; //取出每一位
printf("第%d位是%d\n",ge+1,n);
ge++;
x=x/10;
}
printf("一共是%d位",ge); //输出多少位
return 0;
}

执行结果


习题4.11 输入4个整数按序输出

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#include<stdio.h>
int main()
{
int a,b,c,d,t;
scanf("%d,%d,%d,%d",&a,&b,&c,&d);
if(a>b){
t=a;
a=b;
b=t;
}
if(a>c){
t=a;
a=c;
c=t;
}
if(a>d){
t=a;
a=d;
d=t;
}
if(b>c){
t=b;
b=c;
c=t;
}
if(b>d){
t=b;
b=d;
d=t;
}
if(c>d){
t=c;
c=d;
d=t;
}
printf("%d,%d,%d,%d\n",a,b,c,d); //输出四个数字
return 0;
}

执行结果


第5章 循环结构程序设计

例5.8 斐波拉契数列

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

#include<stdio.h>
int main()
{
int a,b,c;
int flag=2; //记录是第几个数
a=1;
b=1;
printf("第1位的数字是:%d\n",a); //先输出前两个数
printf("第2位的数字是:%d\n",b);
for(int i=1;i<39;i++){ //循环40次
c=a+b; //当前值是前两者之和
flag++; //成功计算一次+1
printf("第%d位的数字是:%d\n",flag,c);
//替换新的a和b
a=b; //递推方式
b=c;
}
return 0;
}

执行结果


例5.10 100-200之内素数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include<stdio.h>
#include<math.h> //要用sqrt函数
int main()
{
//求100-200所有素数
for(int i=100;i<200;i++){
int k=sqrt(i); //开根号
int flag=0; //标志位
for(int j=2;j<=k;j++){ //从2-k就可以
if(i%j==0){
flag=1; //能被整除就不是素数设置为1
}
}
if(flag==0){
printf("%d\n",i); //flag没变就是素数
}
}

return 0;
}

执行结果


习题5.3 求最大公约数和最小公倍数

具体代码

1
2


执行结果


习题5.4 分析字符串组成

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

#include<stdio.h>
int main()
{
int a=0; //统计英文字母个数
int b=0; //统计空格个数
int c=0; //统计数字个数
int d=0; //统计其他字符个数
char temp; //c语言没有字符串string类 所以用char输入
while((temp=getchar())!='\n'){ //换行键就结束
if((temp>='a'&&temp<='z')||(temp>='A'&&temp<='Z')){
a++;
}else if(temp>='0'&&temp<='9'){
c++;
}else if(temp==' '){
b++;
}else {
d++;
}
}
printf("英文字符的个数是:%d\n",a); //输出对应个数
printf("空格字符的个数是:%d\n",b);
printf("数字的个数是:%d\n",c);
printf("其他字符的个数是:%d\n",d);
return 0;
}

执行结果


习题5.8 水仙花数

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include<stdio.h>
int main()
{
//水仙花数只能在3位数中出现
for(int i=100;i<999;i++){
int a=i/100; // 假以187为例 187/100=1
int b=i/10%10; // 187/10=18 18%10=8
int c=i%10; // 187%10=7
if(a*a*a+b*b*b+c*c*c==i){ //每位的立方次==原数
printf("%d\n",i);
}
}
return 0;
}

执行结果


,