import pandas as pd  # 导入pandas库
import numpy as np #导入numpy库
import matplotlib.pyplot as plt
import seaborn as sns  

import warnings
warnings.filterwarnings('ignore')  # 忽略警告信息
data = pd.read_csv(r'E:\PythonStudy\heart.csv') 
data.isnull()            # 布尔矩阵显示缺失值,这个方法返回一个布尔矩阵,也是dataframe对象,其中True表示是缺失值,False表示不是缺失值。
data.isnull().sum()

data.columns      # 所有列名 data的属性

# 特征名中文映射字典(适配心脏病相关临床数据字段)
feature_name_mapping = {
    'age': '年龄',
    'sex': '性别',
    'cp': '胸痛类型',  # Chest Pain Type
    'trestbps': '静息血压(mm Hg)',  # Resting Blood Pressure
    'chol': '血清胆固醇(mg/dl)',  # Serum Cholesterol
    'fbs': '空腹血糖>120mg/dl',  # Fasting Blood Sugar
    'restecg': '静息心电图结果',  # Resting Electrocardiographic Results
    'thalach': '最大心率',  # Maximum Heart Rate Achieved
    'exang': '运动诱发心绞痛',  # Exercise Induced Angina
    'oldpeak': 'ST段压低(相对于休息状态)',  # ST Depression Induced by Exercise Relative to Rest
    'slope': 'ST段峰值斜率',  # Slope of the Peak Exercise ST Segment
    'ca': '荧光检查显示的主要血管数量',  # Number of Major Vessels Colored by Fluoroscopy
    'thal': '地中海贫血症类型',  # Thallium Stress Test Result
    'target': '是否患病(目标变量)'  # 1=患病, 0=未患病(根据数据常规标注)
}
data_cn = data.rename(columns=feature_name_mapping)
data_cn.head()

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# ---------------------- 1. 定义连续特征列表(与中文映射对应)----------------------
# 基于你指定的连续特征:年龄、静息血压、血清胆固醇、最大心率、ST段压低(相对于休息状态)
# 对应原始字段名(需与DataFrame列名一致)
continuous_features = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']

# (可选)如果需要中文特征名用于图表标题,可结合之前的映射字典
feature_name_mapping = {
    'age': '年龄',
    'trestbps': '静息血压(mm Hg)',
    'chol': '血清胆固醇(mg/dl)',
    'thalach': '最大心率',
    'oldpeak': 'ST段压低(相对于休息状态)'
}

# ---------------------- 2. 创建画布和子图(2行3列)----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决中文显示问题
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 10))  # 2行3列,设置图表大小
axes = axes.flatten()  # 将2x3的二维数组展平为一维数组,方便enumerate遍历

# ---------------------- 3. 用enumerate()遍历连续特征,绘制箱线图----------------------
for idx, feature in enumerate(continuous_features):
    # 绘制箱线图(data为你的数据集,需替换为实际DataFrame名称)
    data.boxplot(column=feature, ax=axes[idx], patch_artist=True,
                 boxprops=dict(facecolor='lightblue'),  # 箱体颜色
                 medianprops=dict(color='red'))  # 中位数线颜色
    
    # 设置子图标题(使用中文映射名)
    axes[idx].set_title(f'{feature_name_mapping[feature]} 箱线图', fontsize=12, fontweight='bold')
    # 设置x轴标签(隐藏,因箱线图x轴无多分类)
    axes[idx].set_xlabel('')
    # 设置y轴标签(使用中文映射名)
    axes[idx].set_ylabel(feature_name_mapping[feature], fontsize=10)
    # 优化刻度标签大小
    axes[idx].tick_params(axis='both', which='major', labelsize=9)

# ---------------------- 4. 隐藏多余的空白子图----------------------
# 连续特征共5个,2行3列共6个子图,需隐藏最后1个(索引5)
for idx in range(len(continuous_features), len(axes)):
    axes[idx].set_visible(False)

# ---------------------- 5. 调整子图间距,避免重叠----------------------
plt.tight_layout()

# 显示图表
plt.show()

# (可选)保存图表
# plt.savefig('连续特征箱线图.png', dpi=300, bbox_inches='tight')

# ---------------------- 1. 沿用之前定义的连续特征列表和中文映射(无需重复定义,此处仅为呼应)----------------------
# continuous_features = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']
# feature_name_mapping 沿用之前的定义

# ---------------------- 2. 创建画布和子图(保持2行3列)----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决中文显示问题
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 10))
axes = axes.flatten()  # 展平为一维数组,方便enumerate遍历

# ---------------------- 3. 用enumerate()遍历特征,绘制小提琴图----------------------
for idx, feature in enumerate(continuous_features):
    # 提取当前特征的数据(替换data为你的数据集名称)
    feature_data = data[feature].dropna()  # 去除缺失值,避免报错
    
    # 绘制小提琴图(violinplot)
    parts = axes[idx].violinplot(feature_data, positions=[0], showmeans=True, showmedians=True)
    
    # 美化小提琴图样式
    for pc in parts['bodies']:
        pc.set_facecolor('lightcoral')  # 琴身颜色
        pc.set_edgecolor('darkred')     # 琴身边框颜色
        pc.set_alpha(0.7)               # 透明度
    
    # 突出显示均值和中位数
    parts['cmeans'].set_color('darkblue')    # 均值线颜色
    parts['cmedians'].set_color('gold')       # 中位数线颜色
    parts['cmeans'].set_linewidth(2)
    parts['cmedians'].set_linewidth(2)
    
    # 设置子图标题和标签
    axes[idx].set_title(f'{feature_name_mapping[feature]} 小提琴图', fontsize=12, fontweight='bold')
    axes[idx].set_xlabel('')  # 隐藏x轴标签
    axes[idx].set_ylabel(feature_name_mapping[feature], fontsize=10)
    axes[idx].tick_params(axis='both', which='major', labelsize=9)
    
    # 调整x轴范围,让小提琴图更居中
    axes[idx].set_xlim(-0.5, 0.5)
    axes[idx].set_xticks([])  # 隐藏x轴刻度

# ---------------------- 4. 隐藏多余的空白子图----------------------
for idx in range(len(continuous_features), len(axes)):
    axes[idx].set_visible(False)

# ---------------------- 5. 调整子图间距,避免重叠----------------------
plt.tight_layout()

# 显示图表
plt.show()

# (可选)保存图表
# plt.savefig('连续特征小提琴图.png', dpi=300, bbox_inches='tight')
# ---------------------- 1. 定义离散特征列表(排除5个连续特征+目标变量)----------------------
# 原始所有特征(参考初始字段列表)
all_features = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg', 
                'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'thal', 'target']
# 已确定的连续特征(5个)
continuous_features = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']
# 目标变量(标签,排除在特征之外)
target = 'target'

# 离散特征 = 所有特征 - 连续特征 - 目标变量
discrete_features = [feat for feat in all_features if feat not in continuous_features and feat != target]

# (沿用之前的完整中文映射字典,确保离散特征都有对应中文)
feature_name_mapping = {
    'age': '年龄',
    'sex': '性别',
    'cp': '胸痛类型',
    'trestbps': '静息血压(mm Hg)',
    'chol': '血清胆固醇(mg/dl)',
    'fbs': '空腹血糖>120mg/dl',
    'restecg': '静息心电图结果',
    'thalach': '最大心率',
    'exang': '运动诱发心绞痛',
    'oldpeak': 'ST段压低(相对于休息状态)',
    'slope': 'ST段峰值斜率',
    'ca': '荧光检查显示的主要血管数量',
    'thal': '地中海贫血症类型',
    'target': '是否患病(目标变量)'
}

# ---------------------- 2. 创建画布和子图(2行4列)----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决中文显示问题
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(18, 10))  # 2行4列,适配8个子图位置
axes = axes.flatten()  # 展平为一维数组,方便enumerate遍历

# ---------------------- 3. 用enumerate()遍历离散特征,绘制条形图----------------------
for idx, feature in enumerate(discrete_features):
    # 统计离散特征各取值的数量(替换data为你的数据集名称)
    value_counts = data[feature].value_counts().sort_index()  # 按索引排序,保证顺序一致
    
    # 绘制条形图
    bars = axes[idx].bar(
        x=value_counts.index.astype(str),  # x轴为特征取值(转为字符串,避免数值类型误解)
        height=value_counts.values,
        color='lightseagreen',
        edgecolor='darkcyan',
        alpha=0.8
    )
    
    # 在条形图顶部添加数值标签
    for bar in bars:
        height = bar.get_height()
        axes[idx].text(
            bar.get_x() + bar.get_width()/2.,  # 水平居中
            height + 0.1,  # 数值在条形上方偏移一点
            f'{int(height)}',  # 显示计数(整数)
            ha='center', va='bottom', fontsize=9
        )
    
    # 设置子图标题和标签
    axes[idx].set_title(f'{feature_name_mapping[feature]} 分布', fontsize=12, fontweight='bold')
    axes[idx].set_xlabel('特征取值', fontsize=10)
    axes[idx].set_ylabel('计数', fontsize=10)
    axes[idx].tick_params(axis='both', which='major', labelsize=9)
    
    # 调整y轴范围,避免数值标签超出画布
    axes[idx].set_ylim(0, max(value_counts.values) * 1.1)

# ---------------------- 4. 隐藏多余的空白子图----------------------
# 离散特征共6个(sex/cp/fbs/restecg/exang/slope/ca/thal?实际计算:13个特征-5连续-1目标=7个?)
# 实际离散特征列表:['sex', 'cp', 'fbs', 'restecg', 'exang', 'slope', 'ca', 'thal'] → 8个,刚好填满2行4列,无需隐藏
# (若实际数据中离散特征数量少于8个,自动隐藏剩余子图)
for idx in range(len(discrete_features), len(axes)):
    axes[idx].set_visible(False)

# ---------------------- 5. 调整子图间距,避免重叠----------------------
plt.tight_layout()

# 显示图表
plt.show()

# (可选)保存图表
# plt.savefig('离散特征条形图.png', dpi=300, bbox_inches='tight')
# ---------------------- 可视化配置(复用)----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
target_name = feature_name_mapping['target']  # 目标变量中文名称

# ---------------------- 1. 连续特征 × 标签:分组小提琴图(2行3列)----------------------
fig1, axes1 = plt.subplots(2, 3, figsize=(15, 10))
axes1 = axes1.flatten()

for idx, feat in enumerate(continuous_features):
    # 按标签分组提取数据(0=未患病,1=患病,根据实际标签取值调整)
    data_0 = data[data['target'] == 0][feat].dropna()
    data_1 = data[data['target'] == 1][feat].dropna()
    
    # 绘制分组小提琴图
    parts = axes1[idx].violinplot([data_0, data_1], positions=[0, 1], showmeans=True, showmedians=True)
    
    # 样式优化(不同标签用不同颜色)
    colors = ['lightblue', 'lightcoral']
    for i, pc in enumerate(parts['bodies']):
        pc.set(facecolor=colors[i], edgecolor=['darkblue', 'darkred'][i], alpha=0.7)
    parts['cmeans'].set(color='black', linewidth=2)
    parts['cmedians'].set(color='gold', linewidth=2)
    
    # 标签设置
    axes1[idx].set_title(f'{feature_name_mapping[feat]} × {target_name}', fontsize=12, fontweight='bold')
    axes1[idx].set_xlabel(target_name, fontsize=10)
    axes1[idx].set_ylabel(feature_name_mapping[feat], fontsize=10)
    axes1[idx].set_xticks([0, 1])
    axes1[idx].set_xticklabels(['未患病(0)', '患病(1)'])  # 按实际标签含义调整
    axes1[idx].tick_params(labelsize=9)

# 隐藏多余子图
for idx in range(len(continuous_features), len(axes1)):
    axes1[idx].set_visible(False)

plt.tight_layout(), plt.show()

# ---------------------- 2. 离散特征 × 标签:分组条形图(2行4列)----------------------
fig2, axes2 = plt.subplots(2, 4, figsize=(18, 10))
axes2 = axes2.flatten()

for idx, feat in enumerate(discrete_features):
    # 按标签分组统计频次(交叉表)
    cross_tab = pd.crosstab(data[feat], data['target'], normalize='index') * 100  # 按特征取值归一化(百分比)
    
    # 绘制分组条形图
    x = np.arange(len(cross_tab.index))
    width = 0.35
    bars1 = axes2[idx].bar(x - width/2, cross_tab[0], width, label='未患病(0)', color='lightblue', edgecolor='darkblue', alpha=0.8)
    bars2 = axes2[idx].bar(x + width/2, cross_tab[1], width, label='患病(1)', color='lightcoral', edgecolor='darkred', alpha=0.8)
    
    # 添加百分比标签
    for bars in [bars1, bars2]:
        for bar in bars:
            height = bar.get_height()
            axes2[idx].text(bar.get_x() + bar.get_width()/2, height + 1,
                           f'{height:.1f}%', ha='center', va='bottom', fontsize=8)
    
    # 标签设置
    axes2[idx].set_title(f'{feature_name_mapping[feat]} × {target_name}', fontsize=12, fontweight='bold')
    axes2[idx].set_xlabel(f'{feature_name_mapping[feat]} 取值', fontsize=10)
    axes2[idx].set_ylabel('占比(%)', fontsize=10)
    axes2[idx].set_xticks(x)
    axes2[idx].set_xticklabels(cross_tab.index.astype(str))
    axes2[idx].legend(fontsize=9)
    axes2[idx].set_ylim(0, 105)  # 预留百分比标签空间
    axes2[idx].tick_params(labelsize=9)

# 隐藏多余子图
for idx in range(len(discrete_features), len(axes2)):
    axes2[idx].set_visible(False)

plt.tight_layout(), plt.show()
# ---------------------- 1. 计算特征相关性矩阵(仅用特征,排除目标变量)----------------------
# 合并连续+离散特征(排除target)
all_used_features = continuous_features + discrete_features
corr_matrix = data[all_used_features].corr()  # 计算Pearson相关系数

# ---------------------- 2. 定义3种常用配色方案 ----------------------
cmap_list = [
    'RdBu_r',    # 红-蓝反向(经典对比色,正相关红、负相关蓝)
    'YlOrRd',    # 黄-橙-红(暖色调,适合突出正相关)
    'coolwarm'   # 冷-暖过渡(柔和对比,适合多特征场景)
]

# ---------------------- 3. 循环绘制3种配色热力图 ----------------------
for i, cmap in enumerate(cmap_list, 1):
    plt.figure(figsize=(12, 10))  # 固定画布大小,保证清晰度
    
    # 绘制热力图
    im = plt.imshow(corr_matrix, cmap=cmap, aspect='auto', vmin=-1, vmax=1)
    
    # 添加数值标注(保留2位小数,增强可读性)
    for x in range(len(corr_matrix.index)):
        for y in range(len(corr_matrix.columns)):
            plt.text(y, x, f'{corr_matrix.iloc[x, y]:.2f}', 
                    ha='center', va='center', fontsize=8,
                    color='white' if abs(corr_matrix.iloc[x, y]) > 0.5 else 'black')  # 高相关用白字
    
    # 标签与刻度设置(用中文特征名)
    chinese_labels = [feature_name_mapping[feat] for feat in all_used_features]
    plt.xticks(range(len(all_used_features)), chinese_labels, rotation=45, ha='right', fontsize=10)
    plt.yticks(range(len(all_used_features)), chinese_labels, fontsize=10)
    
    # 添加颜色条(标注相关系数范围)
    cbar = plt.colorbar(im, shrink=0.8)
    cbar.set_label('Pearson 相关系数', fontsize=12)
    cbar.ax.tick_params(labelsize=9)
    
    # 标题与布局
    plt.title(f'特征相关性热力图(配色:{cmap})', fontsize=14, fontweight='bold', pad=20)
    plt.tight_layout()  # 自动调整布局,避免标签截断
    
    # 保存图片(清晰度300dpi),可替换路径
    plt.savefig(f'特征相关性热力图_{cmap}.png', dpi=300, bbox_inches='tight')
    plt.close()  # 关闭当前图,避免内存占用

print("3种配色热力图已保存(dpi=300),分别为:RdBu_r、YlOrRd、coolwarm")

图:

1.连续变量的箱线图

2.连续变量的小提琴图

3.离散变量的条形图

4.连续变量与标签的关系图(小提琴图)

5.离散变量与标签的关系图(条形图)

6.热力图

@浙大疏锦行

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐