2021MathorCup高校数学建模挑战赛——大数据竞赛的一些想法总结


1 前言


2021年MathorCup大数据挑战赛A题是个十分典型的大数据类赛题,赛题所给数据文件超大,常规Excel只能部分显示(Excel只能显示1048576行),文件大小8.61GB。如果采用python直接读入的话,整个程序会卡死;Matlab导入同样也会卡住;利用数据库读入,直接报错空间不足。(我用的是本地数据库,非本地应该可以)这些情况都是日常数据分析与处理中没有遇见过的,一般日常做一些数据分析最多百万条数据,撑死千万级别,这次的分析量达到了亿级别。对于这题,最难的就是数据处理部分了,题目本身不难。话不多说,直接开始:
以下皆是本人对这题的一些粗浅的看法,仅供参考。


2 数据预处理


2.1 数据文件的分割


数据集样式:
在这里插入图片描述
既然常规方法无法奏效,那么我们可以通过利用Python创建可操作的文件对象,通过操作指针逐行读取并分割文件进行查看。(其他语言同样可以,感兴趣的可以去尝试一下)

#--- 按照数据条目进行文件数据的分割
import time
import os

#-- 创建一个文件操作对象
file_obj = open(r"D:\2020MathorCup大数据挑战赛\赛道A\赛道A附件\附件1:训练数据\训练用数据.csv")
interval = 2500000 # 分割细度

# -- 逐行读取数据并分割
def concentSave(number_flag):
    '''
    根据number_flag设置文件路径,获取分割文件指针,以便存入数据
    '''
    # 创建文件夹
    folder = 'D:/data'
    if not os.path.exists(folder):
        os.makedirs(folder)
    
    # 获取文件指针
    file_path = 'D:/data/dataset' + str(number_flag) + '.csv'
    fp = open(file_path, 'w')
    return fp

def fileReadLines(file_obj, interval):
    '''
    利用循环移动文件指针逐行读取,设置条目进行分割
    '''
    flag = -1  # 标记数据条目,-1是为了去除表头导致的数据条目不统一
    number_flag = 1  # 标记分割文件数目

    # 获取文件指针
    file_pointer = concentSave(number_flag)

    for line in file_obj:
        if flag == -1:
            pass
        elif flag == 0:
            file_pointer.write(line)
            flag = flag + 1
        else:
            if flag % interval != 0:
                file_pointer.write(line)
            else:
                file_pointer.write(line)
                file_pointer.close()  # 关闭文件指针
                number_flag = number_flag + 1
                # 开启一个新的文件指针
                file_pointer = concentSave(number_flag)  
        flag = flag + 1

    file_pointer.close()
    return flag

time_start = time.time()
data_number = fileReadLines(file_obj, interval)
time_end = time.time()

print('time cost',time_end-time_start,'s')
print('文件:训练用数据.csv\n数据条目:' + str(data_number) + '(含表头)')

对文件进行分割后就可以逐个打开查看一下数据样式了,通过观察我们发现数据都是按照日期排布的,但一天的不同时刻以及不同小区编号的数据是无序的。【也即,数据都是按照天数排好的,但每一天对应时刻的数据以及每个小区所对应的在这一天的数据都是混乱的】

#--- 获取小区编号最大值以及各个小区的数据个数
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import time

#-- 创建一个文件操作对象
file_obj = open(r"D:\2020MathorCup大数据挑战赛\赛道A\赛道A附件\附件1:训练数据\训练用数据.csv")
number = 130000 # 预设的最大小区编号
# 这里预设是想减少赋值操作进行的次数(通过查看数据发现有编号在130000之上)
flag = 1
for line in file_obj:
    if flag == 1:
        flag = flag + 1
        id_number = 0
    else:
        id_number = int(line.split(',')[-3])
               
    if id_number > number:
        number = id_number
file_obj.close()
print('小区编号最大值:' + str(number))

#-- 创建一个存储小区编号对应数据条目的集合
id_array = np.zeros((1,number + 1), dtype=np.int32)
time_start = time.time() # 计时开始

flag = 1 # 标记跳过表头
for line in file_obj:
    if flag == 1:
        flag = flag + 1
        continue
    # 比对小区编号,对应数据索引
    id_number = int(line.split(',')[-3])
    id_array[0,id_number] += 1
    
file_obj.close()

id_array = id_array[0,1:] # 去除索引0

time_end = time.time() # 计时结束 
print('time cost:', time_end - time_start, 's') 

#--- 将统计结果写入文件
flag = 1
fp = open('C:/Users/Good/Desktop/id_array.csv', 'w')
fp.write('小区编号,记录数\n')
for value in id_array:
    fp.write(str(flag) + ',' + str(value) + '\n')
    flag += 1

【以日期记录每时刻的上下行流量,3/1—4/19共计50天,每天24小时,因此每个小区共计有1200条数据记录。约有132279个小区,部分小区数据存在缺失。】
这样我们就能得到数据集的基本信息了,信息汇总至下表

日期 记录日期:2018/3/1–2018/4/19
时间 起始记录时间:0:00:00,以小时为记录区间
小区编号 预计共有132279个小区,部分小区存在数据缺失
上行业务量GB 从用户侧到网络侧是数据流,则属于上行
下行业务量GB 从网络侧到用户侧的数据流,都属于下行
数据条目 144138200

小区编号对应数据条目写入文件:
在这里插入图片描述
绘制小区编号对应数据条目的分布图:

plt.figure(figsize=(20,10))
matplotlib.rcParams['font.family'] = 'SimHei'
# bins = np.linspace(0,1200,13).tolist()
# bins.append(2500)
fre_tuple = plt.hist(id_array, bins=20, color='steelblue', edgecolor='black', rwidth=0.8, orientation='horizontal')
plt.title('小区流量记录分布直方图', fontproperties='SimHei', fontsize=15)
x_loc = fre_tuple[0] # 频数
y_loc = fre_tuple[1] # 分割区间
for x,y in zip(x_loc,y_loc):
    plt.text(x+2500, y+25, '%.0f' % x, ha='center', va= 'bottom',fontsize=15)
    # x,y 加上的数值可以自己结合要绘制的图形设定,用来调整标签的显示位置
plt.show()

此处代码解释可以查看:matplotlib绘制直方图
代码运行所得图像如下所示:
在这里插入图片描述不难发现部分小区的数据存在重复,记录数大于1200;很多小区数据存在缺失,数据条目不足1000的超过10000个小区
这样数据集的基本信息已经获取,现在开始正式的数据集的按日期分割。
在这里插入图片描述
部分数据日期格式不规范,需要添加条件进行判断。
在这里插入图片描述

#--- 按照日期进行数据的分割
import time
import os

#-- 创建一个文件操作对象
file_obj = open(r"D:\2020MathorCup大数据挑战赛\赛道A\赛道A附件\附件1:训练数据\训练用数据.csv")

def concentSave(filename):
    '''
    根据filename设置文件路径,获取分割文件指针,以便存入数据
    '''
    # 创建文件夹
    folder = 'D:/data'
    if not os.path.exists(folder):
        os.makedirs(folder)
    
    # 按照日期提取文件名
    if '/' in filename:
        name_list = filename.split('/')
        filename = name_list[-2] + '-' + name_list[-1]
    else:
        name_list = filename.split('-')
        if name_list[-1][0] == '0':
            name_list[-1] = name_list[-1][-1]            
        filename = name_list[-2][-1] + '-' + name_list[-1]
         
    # 获取文件指针
    file_path = 'D:/data/' + filename + '.csv'
    fp = open(file_path, 'w')
    return fp

def splitFile(file_obj):
    '''
    按照日期进行数据集的分割
    '''
    datetime_flag = '2018/3/1' # 标记分割日期
    file_number = 1
    flag = 0 # 去除文件表头
    
    # 获取文件指针
    file_pointer = concentSave(datetime_flag)
    
    for line in file_obj:
        if flag == 0:
            pass
        else:
            datetime = line.split(',')[0]
            if datetime == datetime_flag:
                file_pointer.write(line)
            else:
                file_number = file_number + 1
                datetime_flag = datetime
                file_pointer.close()  # 关闭文件指针
                # 获取文件指针
                file_pointer = concentSave(datetime_flag)
                file_pointer.write(line)
        flag = flag + 1  
    file_pointer.close()
    
    return file_number
      
time_start = time.time() # 计时开始    
subFileNumber = splitFile(file_obj) 
time_end = time.time() # 计时结束      
print('time cost:', time_end - time_start, 's')
print('file number:', subFileNumber)

代码运行结果:
在这里插入图片描述


2.2 数据文件的去重

#--- 逐个读入文件进行数据去重
import pandas as pd
from matplotlib import pyplot as plt
import os

# 记录按日期分割后的文件名称
folder = []
for i in range(1,32):
    folder.append('3-' + str(i))
for j in range(1,20):
    if j == 14:
        continue
    else:
        folder.append('4-' + str(j))

#-- 逐个文件去重
read_path = 'D:/A_data/'
save_path = 'D:/deal_data'
if not os.path.exists(save_path):
    os.makedirs(save_path)
for filename in folder:
    file_path = read_path + filename + '.csv'
    data = pd.read_csv(file_path, sep=',', header=None)
    
    # 去除重复值
    data.drop_duplicates(inplace=True)
   	# 存入文件
    data.to_csv(save_path + '/' + filename + '.csv', index=False)

将去重后的各个子文件进行合并,以便在去重后的文件中提取待预测小区的基站流量数据

import os

# 记录按日期分割后的文件名称
folder = []
for i in range(1,32):
    folder.append('3-' + str(i))
for j in range(1,20):
    if j == 14:
        continue
    else:
        folder.append('4-' + str(j))

#-- 合并文件,统计信息
read_path = 'D:/deal_data/'
save_path = 'D:/merge_data'

if not os.path.exists(save_path):
    os.makedirs(save_path)
write_file = open(save_path + '/data.csv', 'w')
number_data = 0
for filename in folder:
    file_path = read_path + filename + '.csv'
    read_file = open(file_path, 'r')
    
    flag = 1 # 设立标记,去除表头

    for line in read_file:
        if flag == 1:
            flag += 1
            continue
        number_data += 1    
        write_file.write(line)
    
    read_file.close()
print(number_data)
write_file.close() 

下面的这部分操作可以不做,我只是想看一下进行处理后的效果。【这部分有很多代码就不全放出来了】
合并数据集,再进行一边上面的操作(提取各小区编号的数据条目等),得到下图
在这里插入图片描述可以看到仍有部分小区数据条目超标:
在这里插入图片描述

超额小区编号 1111, 1112, 32956, 32957, 32958
超额原因 日期、时间、编号相同但流量记录不同,因此重复数据无法剔除
处理方式 排除超额小区编号数据

在这里插入图片描述


3 问题一的求解


在这里插入图片描述


3.1 数据提取


对问题需要预测的小区编号进行提取
在这里插入图片描述

import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
import time
import os

#--- 获取需要短期预测的小区编号
  • 55
    点赞
  • 249
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
2022 mathorcup 高校数学建模挑战赛-赛道b是一个高水平的数学建模竞赛,面向的是各大高校的学生,旨在培养学生的数学建模能力和解决实际问题的思维能力。 在本次比赛中,参赛队伍需要根据题目要求,选择合适的数学方法和模型,对问题进行建模和求解。这些问题往往与实际生活、科学研究和工程技术等领域相关,需要队伍的成员具备扎实的数学基础知识和分析能力。 参赛队伍需要充分利用数学方法,如微积分、高级代数、概率论等,进行数学建模和实际问题求解。他们需要运用数学模型进行问题的分析、预测和决策,将抽象的问题转化为具体的数学表达式,并通过计算机等工具进行求解和验证。 在比赛中,队伍的成员需要充分合作,共同探讨问题的思路和解题方法,形成有机的团队合作。他们需要分工合作,将各自的专长和思维进行充分的整合和利用,以最终得出科学而准确的数学建模结果。 此外,参赛队伍还需要具备良好的时间管理和应变能力。他们需要在有限的时间内完成问题的分析、建模和求解过程,针对可能出现的困难和挑战做出快速而准确的反应。 总之,2022 mathorcup 高校数学建模挑战赛-赛道b是一个提升学生数学建模能力和解决实际问题能力的重要平台。参赛队伍需要充分发挥团队合作精神,灵活运用数学知识和方法,快速解决实际问题,展示他们的才华和潜力。这也是一个锻炼学生综合素质和培养创新思维的宝贵机会。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值