2023 Electrician Cup b question code arrangement

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import os

df = pd.read_excel('附件2:调查数据.xlsx') #, encoding='utf-8'


#print(df)
#df.info()
#df.isnull().any(axis=0) #查看空值
#counts = df.select_dtypes(include=['object']).apply(pd.Series.value_counts)
#print(counts)
#counts.to_excel("counts.xlsx")
#counts2 = df.apply(lambda x: x.value_counts())
#counts2

data=df.drop('序号',axis=1)
data.columns=['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9', 'q10', 
              'q11', 'q12', 'q13', 'q14', 'q15', 'q16', 'q17', 'q18', 'q19', 'q20', 
              'q21', 'q22', 'q23', 'q24', 'q25', 'q26', 'q27', 'q28', 'q29', 'q30']

#data

mapping = {'大一': 1, '大二': 2, '大三': 3, '大四': 4, '是': 1, '否': 0, '没考虑过': -1}
cols = ['q3', 'q7', 'q10', 'q11', 'q12', 'q13', 'q14', 'q15']

for col in cols:
    data[col] = data[col].map(mapping)


data

data.to_excel("data.xlsx")

# 删除文件
if os.path.exists("data.xlsx"):
    os.remove("data.xlsx")
    print("文件已经删除!")
else:
    print("要删除的文件不存在!")

data=pd.get_dummies(data,columns=['q1', 'q2', 'q4', 'q5', 'q6', 'q8', 'q9', 'q11', 
                                  'q16', 'q17', 'q18', 'q19', 'q20', 'q21', 'q22'])

data

# 定义多选题的列名列表
multi_select_cols = ['q23', 'q24', 'q25', 'q26', 'q27', 'q28', 'q29', 'q30']

# 遍历所有多选题,找到包含的所有选项
options = set()
for col in multi_select_cols:
    for val in data[col].fillna('').unique():
        if val:
            val_list = val.split('┋')
            options.update([o.strip() for o in val_list])

# 对于每个选项,新增一列并设置默认值为0
for option in options:
    col_name = f'option_{option}'
    data[col_name] = 0

# 遍历每个多选题样本,填充对应的值
for col in multi_select_cols:
    for i, val in enumerate(data[col].fillna('')):
        if val:
            val_list = val.split('┋')
            for v in val_list:
                option_col = f'option_{v.strip()}'
                data.loc[i, option_col] = 1


data
# 遍历每个多选题,重命名对应的选项列名
for col in multi_select_cols:
    for val in data[col].fillna('').unique():
        if val:
            val_list = val.split('┋')
            for v in val_list:
                old_col_name = f'option_{v.strip()}'
                new_col_name = f'{col}_{v.strip()}'
                data = data.rename(columns={old_col_name: new_col_name})
data.to_excel("data.xlsx")

# 删除文件
if os.path.exists("data.xlsx"):
    os.remove("data.xlsx")
    print("文件已经删除!")
else:
    print("要删除的文件不存在!")

data=data.drop(['q23', 'q24', 'q25', 'q26', 'q27', 'q28', 'q29', 'q30'],axis=1)

data
data.to_excel("data.xlsx")

# 删除文件
if os.path.exists("data.xlsx"):
    os.remove("data.xlsx")
    print("文件已经删除!")
else:
    print("要删除的文件不存在!")

# 替换列名
df3 = data.rename(columns={'q3': 'q3_年级', 'q7': 'q7_是否使用', 'q10': 'q10_是否想获取', 'q12': 'q12_是否会选择', 
                           'q13': 'q13_完成作业', 'q14': 'q14_完成小测验', 'q15': 'q15_完成论文'})
df3.to_excel("df3.xlsx")

df3.head()

correlation matrix

df3.corr()
df3.describe()
# KS检验
def KsNormDetect(df3):   # 输出结果是服从正态分布的数据列的名字
    from scipy.stats import kstest 
    list_norm_T = []   # 用来储存服从正态分布的数据列的名字
    for col in df3.columns:
        u = df3[col].mean()               # 计算均值
        std = df3[col].std()              # 计算标准差
        res=kstest(df3[col], 'norm', (u, std))[1]  # 计算P值
        if res<=0.05:                        # 判断p值是否服从正态分布,p<=0.05 则服从正态分布,否则不服从
            print(f'{col}该列数据服从正态分布------')
            print('均值为:%.3f,标准差为:%.3f' % (u, std))
            print('-'*40)
            list_norm_T.append(col)             
        else:                                # 这一段实际上没什么必要
            print(f'!!!{col}该列数据不服从正态分布**********')
            print('均值为:%.3f,标准差为:%.3f' % (u, std))
            print('*'*40)
#KsNormDetect(df3[['item_price', 'ord_qty']])
KsNormDetect(df3)


# 对待处理数据中心服从正态分布的数据列
def three_sigma(Ser1):  # Ser1:表示传入DataFrame的某一列
    rule = []
    rule = (Ser1.mean()-3*Ser1.std()>Ser1) | (Ser1.mean()+3*Ser1.std()< Ser1)
    out = Ser1.index[rule]
    print(len(out))
    return out          # 返回落在3sigma之外的行索引值
 
def delete_out3sigma(df3, list_norm):  # data:待检测的DataFrame;list_norm:服从正态分布的数据列名 
    out_index = []                      # 保存要删除的行索引
    for col in list_norm:            # 对每一列分别用3sigma原则处理
        index = three_sigma(df3[col])
        out_index += index.tolist()
    delete_ = list(set(out_index))  # 去除 out_index 中的重复元素
    print(f'\n所删除的行索引共计{len(delete_)}个:\n',delete_)
    df3.drop(delete_,inplace=True) # 根据 delete_ 删除对应行的数据
    data3 = df3
    return data3

#delete_out3sigma(df,['item_price','ord_qty'])
#delete_out3sigma(df3)

 drawing

sns.set(font='SimHei')
# Seaborn中设置字体-黑体,解决seaborn中文乱码问题

# 遍历每一列,并绘制对应的箱线图
for column in df3.columns:
    fig, ax = plt.subplots()
    ax.set_title(column)
    ax.boxplot(df3[column])
    plt.show()
# 遍历每一列,并绘制对应的条形图
for column in df3.columns:
    fig, ax = plt.subplots()
    ax.set_title(column)
    ax.hist(df3[column], bins=len(set(df3[column])))
    
    # 统计每列中不同元素的个数并输出
    unique_elements = set(df3[column])
    element_counts = [list(df3[column]).count(element) for element in unique_elements]
    print('Column', column, 'Unique elements:', unique_elements, 'Counts:', element_counts)
    
    plt.show()

Modeling 

# 'q7_是否使用', 'q10_是否想获取', 'q12_是否会选择', 'q13_完成作业', 'q14_完成小测验', 'q15_完成论文'
df4=df3[['q7_是否使用', 'q10_是否想获取', 'q12_是否会选择', 'q13_完成作业', 'q14_完成小测验', 'q15_完成论文']].value_counts()
df4
# Text 2 ,提取自变量和因变量:

X = df3.drop(['q7_是否使用', 'q10_是否想获取', 'q12_是否会选择', 'q13_完成作业', 'q14_完成小测验', 'q15_完成论文'],axis=1)# 特征
y = df3[['q7_是否使用', 'q10_是否想获取', 'q12_是否会选择', 'q13_完成作业', 'q14_完成小测验', 'q15_完成论文']] # 目标变量
X
#分割数据:

from sklearn.model_selection import train_test_split 
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=100)
#用决策树进行尝试:

from sklearn.tree import DecisionTreeClassifier # 导入决策树
# 选择基尼系数作为判断标准,树深度为3
clf_gini = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=0)

clf_gini.fit(X_train, y_train) #训练模型

y_pred_gini = clf_gini.predict(X_test) # 预测模型
y_pred_gini[0:5] # 预测前五个结果
y_pred_gini
#可视化一下:


plt.figure(figsize=(12,8))
from sklearn import tree
tree.plot_tree(clf_gini.fit(X_train, y_train))

or

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MultiLabelBinarizer
from collections import defaultdict
import seaborn as sns
# 加载数据文件
data = pd.read_excel("附件2:调查数据.xlsx")

list(data)
# 前22列采用类别变量进行编码

# 第23列之后的列采用类别变量进行one-hot编码
df = data.iloc[:,23:]
# 对每一列进行多标签二值化编码
mlb = MultiLabelBinarizer()
cols = df.columns
for col in df.columns:
    # 将每一列的数据按照分隔符进行分割
    df[col] = df[col].apply(lambda x: x.split('┋') if isinstance(x, str) else x)
    mlb.fit_transform(df[col])
#     # 将编码结果按照列名展开为新的列
    for i, label in enumerate(mlb.classes_):
        data[f'{col}_{label}'] = df[col].apply(lambda x: 1 if label in x else 0)
data.drop(columns=df.columns,inplace=True)
data

list(data)
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['Simhei']  #显示中文
plt.rcParams['axes.unicode_minus'] = False    #显示负号
# 筛选出单选题所在的列
single_choice_cols = data.columns[1:23]

# 绘制单选题的条形图和饼状图
for col in single_choice_cols:
    # 计算每个选项的出现次数
    value_counts = data[col].value_counts()
    
    # 绘制条形图
    fig, ax = plt.subplots(figsize=(10, 6))
    ax.bar(value_counts.index, value_counts.values)
    ax.set_title(col)
    ax.set_xlabel('Answer Options')
    ax.set_ylabel('Number of Responses')
    plt.show()

    # 绘制饼状图
    fig, ax = plt.subplots(figsize=(10, 6))
    ax.pie(value_counts.values, labels=value_counts.index, autopct='%1.1f%%', startangle=90)
    ax.set_title(col)
    plt.axis('equal')
    plt.show()
# 绘制多选题的条形图和饼状图
for col in data.columns[23:]:
    tmp = data[col].value_counts().sort_index()
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5))
    ax1.bar(tmp.index.astype(str), tmp.values)
    ax1.set_title(f"{col} - Frequency")
    ax1.set_xlabel("Options")
    ax1.set_ylabel("Count")
    ax2.pie(tmp.values, labels=tmp.index, autopct='%1.1f%%')
    ax2.set_title(f"{col} - Percentages")
    plt.show()
# 单选题绘制条形图和饼状图
single_cols = data.columns[1:23]
for col in single_cols:
    col_data = data[col].value_counts()
    col_data.plot(kind='bar', rot=0, title=col)
    plt.show()

    col_data.plot(kind='pie', autopct='%1.1f%%', title=col)
    plt.show()
# 多选题绘制条形图和饼状图
multi_cols = data.columns[23:]
multi_col_dict = {}
for col in multi_cols:
    q_num = int(col.split('、')[0])  # 多选题问题编号
    if q_num not in multi_col_dict:
        multi_col_dict[q_num] = []
    multi_col_dict[q_num].append(col)

for q_num, cols in multi_col_dict.items():
    col_data = data[cols].sum().sort_values(ascending=False)
    col_data.plot(kind='bar', rot=0, title=f'Multi-choice Question {q_num}')
    plt.show()

    col_data.plot(kind='pie', autopct='%1.1f%%', title=f'Multi-choice Question {q_num}')
    plt.show()
data.to_excel("data2.xlsx")

df2=data.drop('序号',axis=1)
sns.set(font='SimHei')
# Seaborn中设置字体-黑体,解决seaborn中文乱码问题


# 遍历每一列,并绘制对应的条形图
for column in df2.columns[:22]:
    fig, ax = plt.subplots()
    ax.set_title(column)
    ax.hist(df2[column], bins=len(set(df2[column])))
    
    # 统计每列中不同元素的个数并输出
    unique_elements = set(df2[column])
    element_counts = [list(df2[column]).count(element) for element in unique_elements]
    print('Column', column, 'Unique elements:', unique_elements, 'Counts:', element_counts)
    
    plt.show()
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
plt.rcParams['font.sans-serif'] = ['Simhei']  #显示中文

#绘制箱线图

plt.figure(figsize=(10,6))
sns.boxplot(data=df2[:22])
plt.title('问题1至22中分布')

plt.show()
# 遍历每一列,并绘制对应的条形图和饼状图
for column in df2.columns[:22]:
    # 绘制条形图
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

    ax1.set_title(column)
    ax1.hist(df2[column], bins=len(set(df2[column])))
    
    # 统计每列中不同元素的个数并输出
    unique_elements = set(df2[column])
    element_counts = [list(df2[column]).count(element) for element in unique_elements]
    print('Column', column, 'Unique elements:', unique_elements, 'Counts:', element_counts)
    
    # 绘制饼状图
    ax2.set_title(column + ' Proportions')
    proportions = [count/len(df2[column]) for count in element_counts]
    labels = list(unique_elements)
    ax2.pie(proportions, labels=labels, autopct='%1.1f%%', startangle=90)

    plt.show()

 

Guess you like

Origin blog.csdn.net/qq_53011270/article/details/131553603