Python编程打卡第七日实战详解
复习日
针对之前学到的所有知识,针对心脏病项目的数据集来完成数据的预处理。
总的来说,换个心脏病二分类的数据集复习前面几天学习的操作,对于一个数据集在进入模型训练之前,我们通常进行以下的操作:
数据加载 → 基础信息查看(缺失值初步统计) → 可视化探索 → 变量编码处理→ 缺失值处理
1.数据加载
# 导入pandas库和读取数据
import pandas as pd
data = pd.read_csv(r'heart.csv')
data.head(10) # 一般读入了都查看一下前几行数据
2.基本信息查看
# 数据基本信息查看一下,分几个代码单元格分别执行
data.info()
data.shape()
data.count()
data.dtypes()
data.isnull().sum()
data.info()展示出的信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 303 entries, 0 to 302
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 age 303 non-null int64
1 sex 303 non-null int64
2 cp 303 non-null int64
3 trestbps 303 non-null int64
4 chol 303 non-null int64
5 fbs 303 non-null int64
6 restecg 303 non-null int64
7 thalach 303 non-null int64
8 exang 303 non-null int64
9 oldpeak 303 non-null float64
10 slope 303 non-null int64
11 ca 303 non-null int64
12 thal 303 non-null int64
13 target 303 non-null int64
dtypes: float64(1), int64(13)
memory usage: 33.3 KB
这个数据集样本数为303,每列非空值也为303,没有缺失值
3.可视化
先分别找出连续变量和离散变量,这里有个麻烦的点就是数据都是数值型,不能像前面学习的内容通过数据类型来判断是不是离散,自己看看每个变量具体的值判断一下,离散变量通常只有有限的几个不同的值,可以使用 data['列名'].nunique() 来查看每列的唯一值数量
for col in data.columns:
print(f'{col}: 有{data[col].unique()}个唯一值')
打印结果如下:
age: 有[63 37 41 56 57 44 52 54 48 49 64 58 50 66 43 69 59 42 61 40 71 51 65 53
46 45 39 47 62 34 35 29 55 60 67 68 74 76 70 38 77]个唯一值
sex: 有[1 0]个唯一值
cp: 有[3 2 1 0]个唯一值
trestbps: 有[145 130 120 140 172 150 110 135 160 105 125 142 155 104 138 128 108 134
122 115 118 100 124 94 112 102 152 101 132 148 178 129 180 136 126 106
156 170 146 117 200 165 174 192 144 123 154 114 164]个唯一值
chol: 有[233 250 204 236 354 192 294 263 199 168 239 275 266 211 283 219 340 226
247 234 243 302 212 175 417 197 198 177 273 213 304 232 269 360 308 245
208 264 321 325 235 257 216 256 231 141 252 201 222 260 182 303 265 309
186 203 183 220 209 258 227 261 221 205 240 318 298 564 277 214 248 255
207 223 288 160 394 315 246 244 270 195 196 254 126 313 262 215 193 271
268 267 210 295 306 178 242 180 228 149 278 253 342 157 286 229 284 224
206 167 230 335 276 353 225 330 290 172 305 188 282 185 326 274 164 307
249 341 407 217 174 281 289 322 299 300 293 184 409 259 200 327 237 218
319 166 311 169 187 176 241 131]个唯一值
fbs: 有[1 0]个唯一值
restecg: 有[0 1 2]个唯一值
thalach: 有[150 187 172 178 163 148 153 173 162 174 160 139 171 144 158 114 151 161
179 137 157 123 152 168 140 188 125 170 165 142 180 143 182 156 115 149
146 175 186 185 159 130 190 132 147 154 202 166 164 184 122 169 138 111
145 194 131 133 155 167 192 121 96 126 105 181 116 108 129 120 112 128
109 113 99 177 141 136 97 127 103 124 88 195 106 95 117 71 118 134
90]个唯一值
exang: 有[0 1]个唯一值
...
slope: 有[0 2 1]个唯一值
ca: 有[0 2 1 3 4]个唯一值
thal: 有[1 2 3 0]个唯一值
target: 有[1 0]个唯一值
可以分析得到每个变量的具体含义:
sex: 性别(0=女性,1=男性)- 离散变量
cp: 胸痛类型(0-3)- 离散变量
fbs: 空腹血糖(0=≤120mg/dl,1=>120mg/dl)- 离散变量
restecg: 静息心电图结果(0-2)- 离散变量
exang: 运动诱发心绞痛(0=否,1=是)- 离散变量
slope: 运动ST段斜率(0-2)- 离散变量
ca: 主要血管数量(0-4)- 离散变量
thal: 地中海贫血(0-3)- 离散变量
target: 0=无心脏病,1=有心脏病 - 最后的分类标签
age: 年龄 - 连续变量
trestbps: 静息血压 - 连续变量
chol: 血清胆固醇 - 连续变量
thalach: 最大心率 - 连续变量
oldpeak: ST段压低 - 连续变量
连续变量和离散变量都分别找到了
discrete_col = ['sex', 'cp', 'fbs', 'restecg', 'exang', 'slope', 'ca', 'thal']
continuous_col = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']
进行数据可视化,先导入库
import matplotlib.pyplot as plot
import seaborn as sns
plot.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置全局字体为支持中文的字体(如微软雅黑)
plot.rcParams['axes.unicode_minus'] = False # matplotlib默认使用Unicode编码显示负号,在某些字体下负号可能显示为方块,关闭即可
选取连续变量'age'画图
sns.boxplot(data = data, x = 'age')
plot.title('年龄的箱线图')
plot.xlabel('年龄')
plot.show()

选取离散变量'sex'画图,虽然是离散变量可以用histplot()画直方图但画出来的效果对于类别型变量(如性别)确实不如countplot()直观
sns.countplot(data = data, x = 'sex')
plot.title('性别')
plot.xlabel('性别 (1=男性, 0=女性)')
plot.ylabel('人数')
plot.show()

画连续变量'age'与最后分类标签的关系图
sns.boxplot(x = 'target', y = 'age', data = data)
plot.title('年龄与患病与否的关系(箱线图)')
plot.xlabel('患病 (0=无心脏病,1=有心脏病)')
plot.ylabel('年龄')
plot.show()
sns.violinplot(x = 'target', y = 'age', data = data)
plot.title('年龄与患病与否的关系(小提琴图)')
plot.xlabel('患病 (0=无心脏病,1=有心脏病)')
plot.ylabel('年龄')
plot.show()
sns.histplot(x = 'age', hue = 'target', data = data, kde = True, element = "step")
plot.title('年龄与患病与否的关系(核密度估计图+直方图)')
plot.xlabel('年龄')
plot.ylabel('人数')
plot.show()



画离散变量'sex'与最后分类标签的关系图
sns.countplot(x = 'sex', hue = 'target', data = data)
plot.title('性别与患病与否的关系')
plot.xlabel('性别')
plot.ylabel('人数')
plot.show()
4.变量编码
之后可以选取离散变量里的无序变量进行独热编码了,有序变量用标签编码,这里不做处理。连续变量不需要编码,通常做标准化或归一化处理
discrete_code_col = ['sex', 'cp', 'fbs', 'restecg', 'exang'] # 根据变量的含义看是否为无序离散变量
original_col_list = data.columns.tolist() # 获取原始列名
# 进行独热编码
data = pd.get_dummies(data, columns = discrete_code_col)
# 找出来编码后增加的列
add_col_list = [col for col in data.columns if col not in original_col_list]
# 独热编码后将bool值转换为Int型
for col in add_col_list:
data[col] = data[col].astype(int) # 类型转换,bool型转换为 int 型
data.head()

5.缺失值补全
这个数据集没有缺失值,但还是回顾一下补全过程。先求平均数、众数或者中位数,再用 fillna() 对有缺失值的各列用各自的统计量进行填补,注意是否有缺失值调用每列 isnull().sum() 结果是否大于零来判断
@浙大疏锦行
作者: (・Д・)ノ