【Excel 数据填充 之 使用平均值填充的方法】

整体逻辑

  1. 首先对数据进行清洗:数据标准化、数据集的切分、删除空数据行等。
  2. 数据中存在空缺,进行填充,使用的方法是用平均值的方法对数据进行填充
  3. 使用smote算法实现数据集的拟合
  4. 调用pandas库绘制每个类别的数据个数图
  5. 保存数据为excel文件,注意:测试集不用传入模型训练!

代码实现

import pandas as pd
import matplotlib.pyplot as plt

'''---------------------使用平均值的方法对数据进行填充-----------------------'''
def mean_train_method(data):
    '''平均值的计算方法'''
    fill_values = data.mean()
    return data.fillna(fill_values)  # 使用均值填充缺失值,pandas读取表格数据,数据清洗。

def mean_train_fill(train_data,train_label):
    '''使用平均值的方法对数据进行填充'''
    data = pd.concat([train_data, train_label], axis=1)
    data = data.reset_index(drop=True)
    A = data[data['矿物类型'] == 0]
    B = data[data['矿物类型'] == 1]
    C = data[data['矿物类型'] == 2]
    D = data[data['矿物类型'] == 3]

    A = mean_train_method(A)  # 按照每个类别的数据进行填充
    B = mean_train_method(B)  # 按照每个类别的数据进行填充
    C = mean_train_method(C)  # 按照每个类别的数据进行填充
    D = mean_train_method(D)  # 按照每个类别的数据进行填充

    df_filled = pd.concat([A, B, C, D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型', axis=1),df_filled.矿物类型


def mean_test_method(train_data, test_data):
    '''根据训练集获取每个类别的平均值,并将训练集的每个类别平均值填充到测试中'''
    fill_values = train_data.mean()
    return test_data.fillna(fill_values)  # 使用均值填充缺失值

def mean_test_fill(train_data,train_label, test_data,test_label):
    '''使用平均值的方法对数据进行填充'''
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)
    test_data_all = pd.concat([test_data, test_label], axis=1)
    test_data_all = test_data_all.reset_index(drop=True)

    A_train = train_data_all[train_data_all['矿物类型'] == 0]
    B_train = train_data_all[train_data_all['矿物类型'] == 1]
    C_train = train_data_all[train_data_all['矿物类型'] == 2]
    D_train = train_data_all[train_data_all['矿物类型'] == 3]

    A_test = test_data_all[test_data_all['矿物类型'] == 0]
    B_test = test_data_all[test_data_all['矿物类型'] == 1]
    C_test = test_data_all[test_data_all['矿物类型'] == 2]
    D_test = test_data_all[test_data_all['矿物类型'] == 3]

    A = mean_test_method(A_train,A_test)  # 按照每个类别的数据进行填充
    B = mean_test_method(B_train,B_test)  # 按照每个类别的数据进行填充
    C = mean_test_method(C_train,C_test)  # 按照每个类别的数据进行填充
    D = mean_test_method(D_train,D_test)  # 按照每个类别的数据进行填充

    df_filled = pd.concat([A, B, C, D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型', axis=1),df_filled.矿物类型



data = pd.read_excel("矿物数据.xls")
data = data[data['矿物类型'] != 'E']#删除特殊的类别E。整个数据集中只存在1个E数据。
null_num = data.isnull()
#.isnull() 会返回一个相同形状的DataFrame,但其中的元素是布尔值(True或False)。
# 如果原始DataFrame中的某个位置是缺失值(通常是NaN,即“Not a Number”),
# 则对应位置在返回的DataFrame中会被标记为True;否则,标记为False。
#注:还有空白处也是nan,isnull未包含空白处。
null_total = null_num.sum()#检测每列中的缺失值

X_whole =  data.drop('矿物类型', axis=1).drop('序号', axis=1)#获取全部特征数据
y_whole = data.矿物类型                #获取全部标签数据


label_dict = {"A": 0, "B": 1, "C": 2, "D": 3} #将数据中的中文标签转换为字符
encoded_labels = [label_dict[label] for label in y_whole]
y_whole = pd.Series(encoded_labels,name='矿物类型')# 将列表转换为Pandas Series


#数据中存在大量字符串数值、\、空格等异常数据。字符串数值直接转换为float,\和空格转换为nan
for column_name in X_whole.columns:
    X_whole[column_name] = pd.to_numeric(X_whole[column_name], errors='coerce')
#pd.to_numeric()函数尝试将参数中的数据转换为数值类型。如果转换失败,它会引发一个异常,
#设置errors='coerce',会将无法转换的值设置为NaN。

"""数据标准化:Z标准化"""
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_whole_Z = scaler.fit_transform(X_whole)
X_whole = pd.DataFrame(X_whole_Z,columns=X_whole.columns)#Z标准化处理后为numpy数据,这里再转换回pandas数据


'''数据集的切分'''
from sklearn.model_selection import train_test_split
x_train_w, x_test_w, y_train_w, y_test_w = \
    train_test_split(X_whole, y_whole, test_size = 0.3, random_state = 50000)


'''数据中存在空缺,进行填充'''
#使用平均值的方法对数据进行填充
x_train_fill,y_train_fill = mean_train_fill(x_train_w,y_train_w)
#测试集的填充
x_test_fill,y_test_fill = mean_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

'''smote算法实现数据集的拟合'''
from imblearn.over_sampling import SMOTE
oversampler = SMOTE(k_neighbors=1, random_state=42)#数据对象
os_x_train, os_y_train = oversampler.fit_resample(x_train_fill, y_train_fill)#人工拟合的只是训练集。

# 绘制每个类别的数据个数图
y_whole = pd.concat([os_y_train,y_test_fill])
labels_count = pd.value_counts(y_whole)#统计data['矿物类型']中每类的个数
fig, ax = plt.subplots()# 创建一个条形图
bars = ax.bar(labels_count.index,labels_count.values)# 绘制条形图
for bar in bars:    # 遍历每个条形
    yval = bar.get_height()#用于获取条形图 中某个具体条形的高度
    # 在条形上添加文本,使用bar.get_x() + bar.get_width() / 2获取条形的中心
    ax.text(bar.get_x() + bar.get_width() / 2, yval,
            round(yval, 2),  # 你可以在这里选择保留的小数位数
            va='bottom',  # 垂直对齐
            ha='center',  # 水平对齐
            fontsize=10,  # 字体大小
            color='black')  # 字体颜色
plt.xlabel('lables')
plt.ylabel('numbers')
plt.title('The number of data for each category after removing empty data')
plt.show()# 显示图形

'''数据保存为excel文件'''
data_train = pd.concat([os_y_train,os_x_train],axis=1).sample(frac=1, random_state=4)#sample() 方法用于从DataFrame中随机抽取行。frac: 表示抽取行的比例。
data_test = pd.concat([y_test_fill,x_test_fill],axis=1)#测试集不用传入模型训练,无需打乱顺序。


data_train.to_excel(r'.//temp_data//训练数据集[平均值填充].xlsx', index=False)
data_test.to_excel(r'.//temp_data//测试数据集[平均值填充].xlsx', index=False)

  • 19
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值