2023数学建模国赛C题数据预处理代码

数据预处理

注:代码中出现的文件路径改成自己的。

 首先整合几个附件里的数据,先将附件一‘单品名称’、‘单品编码’、‘分类名称’三者建立起关系,因为分类编码一共就6个,可以直接查找,就没有整理到json中。

import pandas as pd
import json

# 读取 Excel 文件
df = pd.read_excel('附件1.xlsx')  

# 定义要包含在 JSON 对象中的列名
columns = ['单品名称', '单品编码', '分类名称']

# 为每一行创建 JSON 对象
json_objects = []
for index, row in df.iterrows():
    json_object = {}
    json_object['item_name'] = row[columns[0]]
    json_object['item_code'] = row[columns[1]]
    json_object['category_name'] = row[columns[2]]
    json_objects.append(json_object)

# 将所有 JSON 对象组成一个 JSON 数组并写入文件
with open('your_json_name.json', 'w') as f:
    json.dump(json_objects, f, indent=2)  # indent=2 用于添加缩进,使 JSON 更易读

# 打印 JSON 对象
for obj in json_objects:
    print(obj)

部分输出结果如下:

{'item_name': '牛首生菜', 'item_code': 102900005115168, 'category_name': '花叶类'}
{'item_name': '四川红香椿', 'item_code': 102900005115199, 'category_name': '花叶类'}
{'item_name': '本地小毛白菜', 'item_code': 102900005115625, 'category_name': '花叶类'}
…………
{'item_name': '海鲜菇(袋)(2)', 'item_code': 106930274620090, 'category_name': '食用菌'}
{'item_name': '绣球菌', 'item_code': 106931885000035, 'category_name': '食用菌'}
{'item_name': '绣球菌(袋)', 'item_code': 106931885000356, 'category_name': '食用菌'}
{'item_name': '金针菇(袋)(3)', 'item_code': 106949711300068, 'category_name': '食用菌'}
{'item_name': '金针菇(袋)(2)', 'item_code': 106949711300167, 'category_name': '食用菌'}
{'item_name': '金针菇(盒)', 'item_code': 106949711300259, 'category_name': '食用菌'}
{'item_name': '白玉菇(2)', 'item_code': 106956146480197, 'category_name': '食用菌'}
{'item_name': '蟹味菇(2)', 'item_code': 106956146480203, 'category_name': '食用菌'}
…………

 然后找到‘单品编码’‘销量(千克)’的Excel文件(附件二),计算每种单品的累加销量,以待后用:

import pandas as pd

# 读取 Excel 文件获取单品编码和销量
sales_data = pd.read_excel('附件2.xlsx')
sales_dict = sales_data.groupby('单品编码')['销量(千克)'].sum().to_dict()

# 累加相同单品编码的销量
accumulated_sales = {}
for item_code, sales in sales_dict.items():
    if item_code in accumulated_sales:
        accumulated_sales[item_code] += sales
    else:
        accumulated_sales[item_code] = sales

# 打印累加后的结果
for item_code, accumulated_sales_value in accumulated_sales.items():
    print(f"单品编码: {item_code}, 累加销量: {accumulated_sales_value}")

输出结果如下: 

……

单品编码: 102900011036266, 累加销量: 3.0

单品编码: 102900011036686, 累加销量: 27.0

单品编码: 102900051000463, 累加销量: 1047.689

单品编码: 102900051000890, 累加销量: 0.671

单品编码: 102900051000944, 累加销量: 745.554

……

这里可以将累加销量的内容保存到txt文件中,以待后用。

再转化为Excel来可视化

import pandas as pd
import json

# 从 output.json 文件读取数据
with open('your_json_name.json', 'r') as file:
    data = json.load(file)

# 将数据转换为 DataFrame
df = pd.DataFrame(data)

# 将数据保存为 Excel 文件
df.to_excel('your_excel_name.xlsx', index=False)
import pandas as pd

# 读取 txt 文件
with open('your_txt_name.txt', 'r') as txt_file:
    lines = txt_file.readlines()

# 处理每一行数据
data = []
for line in lines:
    parts = line.split(',')
    item_code = parts[0].split(': ')[1].strip()
    cumulative_sales = float(parts[1].split(': ')[1].strip())
    data.append([item_code, cumulative_sales])

# 将从 txt 文件中读取的数据转换为 DataFrame
df_txt = pd.DataFrame(data, columns=['item_code', 'cumulative_sales'])

# 读取 Excel 文件
df_excel = pd.read_excel('your_excel_name.xlsx')

# 将 Excel 和 txt 中的单品编码都转换为字符串类型
df_excel['item_code'] = df_excel['item_code'].astype(str)
df_txt['item_code'] = df_txt['item_code'].astype(str)

# 获取 Excel 中单品编码列的数据
excel_item_codes = df_excel['item_code'].values

# 找出 txt 中单品编码在 Excel 中对应的行索引
matching_indices = [i for i, code in enumerate(excel_item_codes) if code in df_txt['item_code'].values]

# 更新累计销量
for index in matching_indices:
    matching_item_code = df_excel.loc[index, 'item_code']
    matching_sales = df_txt[df_txt['item_code'] == matching_item_code]['cumulative_sales'].values[0]
    df_excel.loc[index, 'cumulative_sales'] = matching_sales

# 保存更新后的 Excel 文件
df_excel.to_excel('your_excel_name.xlsx', index=False)

这样就形成了如下形式的excel文件(截取部分):

item_nameitem_codecategory_namecumulative_sales
牛首生菜102900005115168花叶类899.837
四川红香椿102900005115199花叶类333.223
本地小毛白菜102900005115625花叶类121.02
白菜苔102900005115748花叶类718.676
苋菜102900005115762花叶类5100.061
云南生菜102900005115779花叶类15910.46

 

品类丰富度

在此处可以先讨论各个分类的单品个数(即6种蔬菜的品类丰富度),来先进行一步分析:

import pandas as pd

# 读取 Excel 文件
df = pd.read_excel('your_excel_name.xlsx')

# 按 category_name 分组,计算每个组内的 item_name 数量
category_item_count = df.groupby('category_name')['item_name'].nunique()

print(category_item_count)

输出结果如下:
 

category_name
水生根茎类     19
花叶类      100
花菜类        5
茄类        10
辣椒类       45
食用菌       72
Name: item_name, dtype: int64

可以画出对应的饼状图:

import matplotlib.pyplot as plt

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 数据
categories = ['水生根茎类', '花叶类', '花菜类', '茄类', '辣椒类', '食用菌']
counts = [19, 100, 5, 10, 45, 72]

# 计算百分比
total = sum(counts)
percentages = [count / total * 100 for count in counts]

# 绘制饼状图
plt.pie(percentages, labels=categories, autopct='%1.1f%%')
plt.axis('equal')  
plt.title('不同类别占比')
plt.show()

图片如下:

热销单品

从刚刚整理好的Excel文件中找到销量排名前10的单品:

import pandas as pd

# 读取 Excel 文件
df = pd.read_excel('your_excel_name.xlsx')

# 按照"cumulative_sales"列降序排序
sorted_df = df.sort_values(by='cumulative_sales', ascending=False)

# 选取排名前十的单品
top_ten_items = sorted_df.head(10)

# 打印结果
print(top_ten_items[['item_name', 'cumulative_sales']])

输出结果如下:

    item_name  cumulative_sales
148   芜湖青椒(1)         28164.331
100       西兰花         27537.228
106     净藕(1)         27149.440
16        大白菜         19187.218
5        云南生菜         15910.461
241    金针菇(盒)         15596.000
57    云南生菜(份)         14325.000
124    紫茄子(2)         13602.001
180   西峡香菇(1)         11920.227
157    小米椒(份)         10833.000
 

六大品类蔬菜季度平均销量

先从附件2中整理每季度各种单品的销售量:

import pandas as pd

def get_quarter(date):
    month = date.month
    if 1 <= month <= 3:
        return 1
    elif 4 <= month <= 6:
        return 2
    elif 7 <= month <= 9:
        return 3
    else:
        return 4

# 读取 Excel 文件
df = pd.read_excel('附件2.xlsx')

# 将销售日期列转换为日期格式
df['销售日期'] = pd.to_datetime(df['销售日期'])

# 添加季度列
df['季度'] = df['销售日期'].apply(get_quarter)

# 按季度和单品编码分组,计算销量总和
quarterly_sales = df.groupby(['季度', '单品编码'])['销量(千克)'].sum().reset_index()

# 确保单品编码列是字符串类型
quarterly_sales['单品编码'] = quarterly_sales['单品编码'].astype(str)

# 将结果写入 Excel 文件
quarterly_sales.to_excel('quarterly_sales.xlsx', index=False)

获得的quarterly_sales.xlsx截取部分如下:

季度单品编码销量(千克)
1102900005115168171.376
1102900005115199173.268
11029000051152501402.589
1102900005115748684.023
1102900005115762562.951
11029000051157792687.335
1102900005115786284.373
110290000511579354.954
11029000051158231933.838

利用第一步得到的json文件将单品编码对应的单品名称以及分类名称找出来,就可以得到更清晰的关系:

import pandas as pd
import json

# 读取 Excel 文件
quarterly_sales = pd.read_excel('quarterly_sales.xlsx')

# 读取 JSON 文件
try:
    with open('your_json_name.json', 'r') as file:
        code_name_data = json.load(file)
except FileNotFoundError:
    print("The file was not found.")
    code_name_data = []

# 将 JSON 数据转换为 DataFrame
code_name_df = pd.DataFrame(code_name_data)

# 重命名列以匹配现有 DataFrame 中的列名
code_name_df.rename(columns={'item_code': '单品编码', 'item_name': '单品名称', 'category_name': '分类名称'}, inplace=True)

# 使用 merge 将单品名称和分类名称添加到 quarterly_sales DataFrame
quarterly_sales = pd.merge(quarterly_sales, code_name_df, on='单品编码', how='left')

# 如果找不到对应的单品名称或分类名称,则填充特殊的单品编码
quarterly_sales['单品名称'] = quarterly_sales['单品名称'].fillna('SPECIAL_CODE')
quarterly_sales['分类名称'] = quarterly_sales['分类名称'].fillna('SPECIAL_CATEGORY')

# 确保单品编码列是字符串类型
quarterly_sales['单品编码'] = quarterly_sales['单品编码'].astype(str)

# 将更新后的 DataFrame 写入 Excel 文件
quarterly_sales.to_excel('quarterly_sales_updated.xlsx', index=False)

得到的quarterly_sales_updated.xlsx文件截取如下:

季度单品编码销量(千克)单品名称分类名称
1102900005115168171.376牛首生菜花叶类
1102900005115199173.268四川红香椿花叶类
11029000051152501402.589西峡花菇(1)食用菌
1102900005115748684.023白菜苔花叶类
1102900005115762562.951苋菜花叶类
11029000051157792687.335云南生菜花叶类
1102900005115786284.373竹叶菜花叶类
110290000511579354.954小白菜花叶类
11029000051158231933.838上海青花叶类
1102900005115854124.982萝卜叶花叶类

现在只需要对同一个分类的销量按照季度进行累加即可:

import pandas as pd
import matplotlib.pyplot as plt

# 读取 Excel 文件
df = pd.read_excel('quarterly_sales_updated.xlsx')

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 按季度和分类名称分组,并计算每个分组的销量总和
category_sales_by_quarter = df.groupby(['季度', '分类名称'])['销量(千克)'].sum().reset_index()

# 重新排序列以适应季度和分类名称
category_sales_by_quarter = category_sales_by_quarter.pivot(index='季度', columns='分类名称', values='销量(千克)')

# 填充 NaN 值,将没有销量的分类名称设置为 0
category_sales_by_quarter.fillna(0, inplace=True)

# 打印表格
print(category_sales_by_quarter)

# 绘制曲线图
for column in category_sales_by_quarter.columns:
    plt.plot(category_sales_by_quarter.index, category_sales_by_quarter[column], label=column)

plt.xlabel('季度')
plt.ylabel('销量(千克)')
plt.title('各分类季度销量曲线')
plt.legend()
plt.show()

结果如图:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值