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() 结果是否大于零来判断

@浙大疏锦行

作者: (・Д・)ノ

物联沃分享整理
物联沃-IOTWORD物联网 » Python编程打卡第七日实战详解

发表回复