#DAY 8 标签编码与连续变量处理的作业
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
data=pd.read_csv(r"C:\Python Study\Python60DaysChallenge-main\data.csv")
print(‘观察前五行的数据’)
print(data.head())
print(“\n对缺失值进行填补”)
continue_cols=data.select_dtypes(exclude=[‘object’]).columns.tolist()
discrete_cols=data.select_dtypes(include=[‘object’]).columns.tolist()
连续变量:用均值填充缺失值
data[continue_cols] = data[continue_cols].fillna(data[continue_cols].mean())
离散变量:用众数填充缺失值
for col in discrete_cols:
mode_val = data[col].mode()
# 防止众数为空的异常情况
if not mode_val.empty:
data[col] = data[col].fillna(mode_val[0])
调试断点2:确认缺失值全部填充完成
print(“\n=== 缺失值填充后 ===”)
print(“剩余缺失值数量:\n”, data.isnull().sum())
========== 3. 对离散变量进行 one-hot 编码 ==========
data_encoded = pd.get_dummies(data, columns=discrete_cols)
调试断点3:查看编码后的列变化
print(“\n=== 独热编码后 ===”)
print(f"编码后数据形状: {data_encoded.shape}")
print(“新增编码列:”, [col for col in data_encoded.columns if col not in data.columns])
========== 4. 独热编码后的变量转为 int 类型 ==========
筛选出所有独热编码生成的新列
encoded_cols = [col for col in data_encoded.columns if col not in data.columns]
data_encoded[encoded_cols] = data_encoded[encoded_cols].astype(int)
调试断点4:确认类型转换结果
print(“\n=== 类型转换后 ===”)
print(“编码列数据类型:\n”, data_encoded[encoded_cols].dtypes)
print(“处理后数据前5行:\n”, data_encoded.head())
#接下来是连续特征的处理
手动实现归一化
对Annual Income列做归一化,手动构建函数实现
自行学习下如何创建函数,这个很简单很常用
def manual_normalize(data):
“”"
此函数用于对输入的数据进行归一化处理
:param data: 输入的一维数据(如 Pandas 的 Series)
:return: 归一化后的数据
“”"
min_val = data.min()
max_val = data.max()
normalized_data = (data - min_val) / (max_val - min_val)
return normalized_data
for col_name in continue_cols:
# 调用自定义归一化函数覆盖原列
data_encoded[col_name] = manual_normalize(data_encoded[col_name])
打印归一化后的所有连续列
print(“\n归一化后的连续特征:”)
print(data_encoded[continue_cols])
========== 全局配置必须放在所有绘图之前 ==========
设置全局字体为支持中文的字体,解决中文显示为方块的问题
plt.rcParams[‘font.sans-serif’] = [‘SimHei’]
解决负号’-'显示为方块的问题
plt.rcParams[‘axes.unicode_minus’] = False
print(“\n===== 开始绘制单特征可视化 =====”)
1. 连续特征:箱线图 + 直方图(核密度)
for col in continue_cols:
# 箱线图:看分布、四分位数、异常值
plt.figure(figsize=(8, 5))
sns.boxplot(x=data[col])
plt.title(f’{col} 箱线图’)
plt.xlabel(col)
plt.show()
# 直方图+核密度:看数值分布形态 plt.figure(figsize=(8, 5)) sns.histplot(data[col], kde=True) plt.title(f'{col} 分布直方图') plt.xlabel(col) plt.ylabel('样本数量') plt.show()2. 离散特征:计数柱状图(统计每个类别的样本量)
for col in discrete_cols:
plt.figure(figsize=(8, 5))
# 离散分类特征用countplot统计频次,才是正确的“离散特征直方图”
sns.countplot(x=data[col])
plt.title(f’{col} 类别数量分布’)
plt.xlabel(col)
plt.ylabel(‘样本数量’)
# 类别名称过长时可以旋转x轴标签,避免重叠
plt.xticks(rotation=30)
plt.show()
===================== 二、特征与标签的关系可视化 =====================
print(“\n===== 开始绘制特征与标签关系图 =====”)
1. 连续特征 vs 违约标签:分组箱线图
逻辑:按违约状态分组,对比不同群体的特征数值分布差异
for col in continue_cols:
plt.figure(figsize=(8, 5))
sns.boxplot(x=target, y=col, data=data)
plt.title(f’{col} 与信用违约的关系’)
plt.xlabel(‘是否信用违约’)
plt.ylabel(col)
plt.show()
2. 离散特征 vs 违约标签:分组计数图
逻辑:按特征类别分组,再拆分违约/未违约,看不同类别下的违约占比差异
for col in discrete_cols:
plt.figure(figsize=(10, 6))
sns.countplot(x=col, hue=target, data=data)
plt.title(f’{col} 与信用违约的关系’)
plt.xlabel(col)
plt.ylabel(‘样本数量’)
plt.xticks(rotation=30)
plt.legend(title=‘是否违约’)
plt.show()