浅谈Python数学建模之数据导入


Posted in Python onJune 23, 2021
目录
  • 一、数据导入是所有数模编程的第一步
  • 二、在程序中直接向变量赋值
    • 2.1、为什么直接赋值?
    • 2.2、直接赋值的问题与注意事项
  • 三、Pandas 导入数据
    • 3.1、Pandas 读取 Excel 文件
    • 3.2、Pandas 读取 csv 文件
    • 3.3、Pandas 读取文本文件
    • 3.4、Pandas 读取其它文件格式
  • 四、数据导入例程

 

一、数据导入是所有数模编程的第一步

编程求解一个数模问题,问题总会涉及一些数据。

有些数据是在题目的文字描述中给出的,有些数据是通过题目的附件文件下载或指定网址提供的,还有些数据是需要自己搜集的。不论是哪种方式获得的数据,也不论哪种类型的问题和算法,首先都是要把这些数据以适当的方式和格式导入到程序中。

如果数据格式有问题,轻则读取数据时发生错误,要浪费时间去查找和解决,在数模竞赛中就会让人非常焦躁。数据错误还是轻的吗?对,重则读取数据有错误,程序却在继续运行,得到了错误的结果,这在数模竞赛中就更糟糕了。你可能都不知道发生了错误,就算感觉有问题也不会把错误直接锁定到数据导入部分,结果不停地去修改其它模块,直到把正确的模块也搞错了,最后无可救药。

因此,确保数模编程第一步“数据导入”的顺利完成,比原先的想象更重要。赛题所给数据文件中的数据组织方式不同,也需要使用不同的方法来导入数据。

那么好了,既然是要具体问题具体分析,这不跟没说一样吗?这正是本文希望回答的问题,虽然针对不同问题的最佳的数据导入方法也不同,但我们先要学会一种未必最佳,但是通用、安全、简单、好学的方法。

 

二、在程序中直接向变量赋值

直接在程序中向变量赋值,是虽然笨拙但最简单的方法,也许还是最可靠的方法——如果你没有敲错键盘的话。

确实,把直接赋值作为数据导入方法来介绍,实在是不好意思说出口。但是,对于数模竞赛这种特殊的需求,直接赋值的方法还是十分常用的,而且完全符合简单、实用、可靠的要求。

不过,直接赋值也并非我们想的那么简单,还是值得认真地谈一谈。

 

2.1、为什么直接赋值?

绝大部分数学建模教材中的例程,都是使用直接赋值的方法导入数据。很大比例的博客例程,包括本系列的大多数案例,也都是在程序中直接赋值的。

其原因在于,一是为了保证程序的完整性,复制粘贴回车就能得到运行结果,不需要复制数据文件等操作,就避免了由此引起的各种错误;二是为了把读者的注意力聚焦在主要的知识点,避免干扰;三是使例程更加直观易懂,便于理解例程的算法。

这些原因也都是直接赋值的优点。那么,这些优点不也正是数模竞赛编程活动的痛点吗?没错,这就是直接赋值方法在数学建模培训和数模竞赛编程的实践中广泛流行的原因。

 

2.2、直接赋值的问题与注意事项

但是,即使在数模竞赛编程中,直接赋值也会有几个问题。

一是某些问题不能使用直接赋值方法。这主要是大数据的问题,数据量或数据文件的数量极大,已经不能使用直接赋值实现了。

二是一些问题虽然可以直接赋值,但很容易出错。这主要是数据量很大,或者数据结构、类型比较复杂的问题。

例如,多元分析、时间序列、数据统计类的题目可能都有很大的数据量,在附件中提供数据文件。这时如果在使用直接赋值导入数据,不再是敲键盘了,而是从文件中把数据复制粘贴到程序中。

这时要特别注意的问题是:

  • 文件中的数据分隔符是什么,空格还是逗号,与变量赋值的格式要求是否一致?
  • 即使文件中的数据分隔符看上去是空格,也需要检查到底是空格还是制表符,是一个空格还是几个空格?
  • 文件中的数据有没有错漏等异常?这在读取文件中可以通过程序检查、识别和处理,在复制粘贴时就要人工处理了。

三是数据量不大的问题,完全可以用直接赋值导入数据,但也会由于疏忽大意而出错。

这倒不是说敲错键盘了,而是由于例程不一定是把数据赋值作为独立模块处理的,而是分散在算法的过程中进行赋值。同学在使用和修改例程时时,就很容易忘记修改算法过程中的变量赋值。这种情况屡见不鲜,有时是因为对程序没有搞明白,忽略了算法步骤中的某个变量;更多时候是忙中出错,在反复调试和更换数据时晕头转向,只顾了修改开始的数据而疏忽了后面的数据。

养成数据导入模块化的习惯,才能避免这一类的疏忽:

  • 将数据导入模块作为单独的函数。
  • 如果不愿意使用数据导入函数,则要把数据导入部分集中写成一段,放在程序的起始部分。
  • 不要把问题本身的数据导入与算法所需的参数赋值混淆,分为两个独立的函数或段落。

例程 1:将数据导入作为单独的函数

# 子程序:定义优化问题的目标函数
def cal_Energy(X, nVar, mk): # m(k):惩罚因子
    p1 = (max(0, 6*X[0]+5*X[1]-320))**2
    p2 = (max(0, 10*X[0]+20*X[1]-7027)**2
    fx = -(10*X[0]+9*X[1])
    return fx+mk*(p1+p2)

# 子程序:模拟退火算法的参数设置
def ParameterSetting():
    tInitial = 100.0            # 设定初始退火温度(initial temperature)
    tFinal  = 1                 # 设定终止退火温度(stop temperature)
    alfa    = 0.98              # 设定降温参数,T(k)=alfa*T(k-1)
    nMarkov = 100            	# Markov链长度,也即内循环运行次数
    youcans = 0.5               # 定义搜索步长,可以设为固定值或逐渐缩小
    return tInitial, tFinal, alfa, nMarkov, youcans

例程 2:将数据导入集中写成一段,放在程序的起始部分

# 主程序
def main():
    # 模型数据导入
    p1 = [6, 5, -320]
    p2 = [10, 20, -7027]
    p3 = [10, 9]
    print(p1,p2,p3)

    # 算法参数设置
    tInitial = 100.0            # 设定初始退火温度(initial temperature)
    tFinal  = 1                 # 设定终止退火温度(stop temperature)
    alfa    = 0.98              # 设定降温参数,T(k)=alfa*T(k-1)
    nMarkov = 100            	# Markov链长度,也即内循环运行次数
    youcans = 0.5               # 定义搜索步长,可以设为固定值或逐渐缩小
    print(tInitial, tFinal, alfa, nMarkov, youcans)

 

三、Pandas 导入数据

虽然很多数模竞赛的问题可以通过直接赋值获取数据,但主流的数据导入方法还是读取数据文件。

数学建模中常用的数据文件格式有文本文件(.txt)、Excel 文件(.xls, .xlsx)和 csv 文件(.csv)。

在读取文本文件时,会遇到逗号、空格、制表符等不同的数据分割符。读取 Excel 文件时,首先 .xls 与 .xlsx 的格式不同,其次要考虑数据表带不带标题行,有时文件中还有多个工作表。读取文件时还会遇到数据缺失,非法字符。对于小白来说,特别在竞赛时,处理这些问题时都会心神不宁。

Python 中读取数据文件的方法也很多。本文非常不推荐使用 Python 自身的文件操作如打开(open)、关闭(close)、读写(read、readline)函数,而是推荐使用 Pandas 读取数据文件。原因在于:

  • Pandas 提供了多种常用文件格式的读写函数,以上各种情况都能一行代码搞定。
  • Pandas 是基于 NumPy 构建的数据分析工具包,便于进行数据整理与清洗,操作方便灵活。
  • Pandas 提供了与其它各种数据结构的转换工具,使用简单灵活。
  • 很多数学建模算法的例程就是使用 Pandas 的 Series、DataFrame 数据结构,无需进行转换。

 

3.1、Pandas 读取 Excel 文件

Pandas 使用 read_excel() 函数读取 Excel文件。

pd.read_excel(io, sheetname=0,header=0,index_col=None,names=None)

pd.read_excel() 的主要参数:

  • io : 文件路径(包括文件名)。
  • header :指定作为列名的行。默认为 0,即首行为标题行。设置 header=None,表示无标题行,首行就是数据行。
  • sheetname:指定工作表。默认为 sheetname=0。设置 sheetname=None 返回全表, 设置 sheetname=[0,1] 返回多表 。
  • index_col :指定作为行索引的列编号或列名。
  • names:指定列名, 类型为 list。

pd.read_excel() 使用实例:

# sheetname 表示读取指定的工作表,header=0 表示首行为标题行,header=None 表示首行为数据行
df = pd.read_excel("data/youcans1.xls", sheetname='Sheet1', header=0)

 

3.2、Pandas 读取 csv 文件

**Pandas 使用 pandas.read_csv() 函数读取 Excel文件。 **

pd.read_csv( filepath ,sep=',', header='infer', names=None, index_col=None)

pd.read_csv() 的主要参数:

  • filepath : 文件路径(包括文件名)。
  • sep:指定分隔符。默认为逗号 ',',可根据需要设置其它分隔符。
  • header :指定作为列名的行。如果文件没有列名则默认为 0,表示首行就是数据行;设置 header=None,表示无标题行,首行就是数据行。
  • index_col :指定作为行索引的列编号或列名。
  • names:指定列名, 类型为 list。

pd.read_csv() 使用实例:

# sep=','表示间隔符为逗号,header=0表示首行为标题行,header=None 表示首行为数据行
df = pd.read_csv("data/youcans2.csv", header=0, sep=',')

 

3.3、Pandas 读取文本文件

**对于文本文件 .txt 和 .dat,可以使用 pandas.read_table() 函数读取 。 **

pd.read_csv( filepath ,sep='\t', header='infer', names=None, index_col=None)

pd.read_table() 的主要参数:

  • filepath : 文件路径(包括文件名)。
  • sep:指定分隔符。默认为 tab 制表符,可根据需要设置其它分隔符。
  • header :指定作为列名的行。如果文件没有列名则默认为 0,表示首行就是数据行;设置 header=None,表示无标题行,首行就是数据行。
  • index_col :指定作为行索引的列编号或列名。
  • names:指定列名, 类型为 list。

pd.read_table() 使用实例:

# sep='\t'表示分隔符为制表符,header=None 表示无标题行,第一行是数据
df = pd.read_table("data/youcans3.dat", sep="\t", header=None)

 

3.4、Pandas 读取其它文件格式

Pandas 还提供了读取多种文件格式的函数,使用方法也都类似,都是一行代码搞定。例如:

  • pandas.read_sql,读取 SQL 数据库
  • pandas.read_html,抓取网页中的表格数据
  • pandas.read_json,读取 JSON 数据文件
  • pandas.read_clipboard,读取剪贴板内容

由于这些文件格式中数模竞赛中很少用到,本文就不进行详细介绍了。有需要的同学可以根据函数名通过搜索引擎搜索参考资料,也可以查阅官方文档:

Pandas 输入输出函数的说明文档

Input/output — pandas 1.2.4 documentation (pydata.org)

https://pandas.pydata.org/pandas-docs/stable/reference/io.html

此外,对于大数据类的问题,所需处理的数据量可能非常大,必要时需对文件进行拆分或合并,也可以用 pandas 进行处理,这将在后续文章结合具体问题进行讲解。

 

四、数据导入例程

【重要说明】以上章节的内容虽然介绍了数据导入的基本方法,但恐怕还是难以达到消化吸收,为我所用。为了解决这个问题,本文将相关内容整合为例程,以便于读者学习收藏,也便于使用修改。

例程01:读取数据文件

import pandas as pd

# 读取数据文件
def readDataFile(readPath):  # readPath: 数据文件的地址和文件名
    # readPath = "../data/youcansxupt.csv"  # 文件路径也可以直接在此输入
    try:
        if (readPath[-4:] == ".csv"):
            dfFile = pd.read_csv(readPath, header=0, sep=",")  # 间隔符为逗号,首行为标题行
            # dfFile = pd.read_csv(filePath, header=None, sep=",")  # sep: 间隔符,无标题行
        elif (readPath[-4:] == ".xls") or (readPath[-5:] == ".xlsx"):  # sheet_name 默认为 0
            dfFile = pd.read_excel(readPath, header=0)  # 首行为标题行
            # dfFile = pd.read_excel(filePath, header=None)  # 无标题行
        elif (readPath[-4:] == ".dat"):  # sep: 间隔符,header:首行是否为标题行
            dfFile = pd.read_table(readPath, sep=" ", header=0)  # 间隔符为空格,首行为标题行
            # dfFile = pd.read_table(filePath,sep=",",header=None) # 间隔符为逗号,无标题行
        else:
            print("不支持的文件格式。")
    except Exception as e:
        print("读取数据文件失败:{}".format(str(e)))
        return
    return dfFile

# 主程序
def main():

    # 读取数据文件 # Youcans, XUPT
    readPath = "../data/toothpaste.csv"  # 数据文件的地址和文件名
    dfFile = readDataFile(readPath)  # 调用读取文件子程序
    
    print(type(dfFile))  # 查看 dfFile 数据类型
    print(dfFile.shape)  # 查看 dfFile 形状(行数,列数)
    print(dfFile.head())  # 显示 dfFile 前 5 行数据

    return

if __name__ == '__main__':  # Youcans, XUPT
    main()

例程01 运行结果:

<class 'pandas.core.frame.DataFrame'>

(30, 6)

   period  price  average  advertise  difference  sales

0       1   3.85     3.80       5.50       -0.05   7.38

1       2   3.75     4.00       6.75        0.25   8.51

2       3   3.70     4.30       7.25        0.60   9.52

3       4   3.70     3.70       5.50        0.00   7.50

4       5   3.60     3.85       7.00        0.25   9.33

例程01 程序说明:

1.本例程需要读取数据文件 "../data/toothpaste.csv",该文件保存在 ../data/ 目录下。读者需要修改该数据文件的文件路径和文件名,以便读取自己需要的本地文件。

2.本例程可以根据文件名的后缀自动识别文件类型,调用相应的函数读取文件。

3.本例程中读取文件模块使用 try...except 语句进行简单的异常处理。如果读取失败,可以根据抛出的异常类型查找错误。

以上就是浅谈Python数学建模之数据导入的详细内容,更多关于Python 数学建模 数据导入的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python里隐藏的“禅”
Jun 16 Python
Python lambda和Python def区别分析
Nov 30 Python
用Python脚本来删除指定容量以上的文件的教程
May 04 Python
python实现的简单抽奖系统实例
May 22 Python
Python获取邮件地址的方法
Jul 10 Python
在Django框架中编写Context处理器的方法
Jul 20 Python
python3编码问题汇总
Sep 06 Python
Python面向对象总结及类与正则表达式详解
Apr 18 Python
20行python代码的入门级小游戏的详解
May 05 Python
tensorflow 变长序列存储实例
Jan 20 Python
使用Python FastAPI构建Web服务的实现
Jun 08 Python
如何在vscode中安装python库的方法步骤
Jan 06 Python
python四种出行路线规划的实现
浅谈Python数学建模之线性规划
Jun 23 #Python
教你如何用Python实现人脸识别(含源代码)
python 对图片进行简单的处理
DjangoRestFramework 使用 simpleJWT 登陆认证完整记录
浅析Python中的套接字编程
Python中使用ipython的详细教程
You might like
PHP生成静态页面详解
2006/11/19 PHP
phpmailer中文乱码问题的解决方法
2014/04/22 PHP
PDO防注入原理分析以及注意事项
2015/02/25 PHP
详解WordPress中提醒安装插件以及隐藏插件的功能实现
2015/12/25 PHP
分析PHP中单双引号的误区和双引号小隐患
2016/07/19 PHP
javascript getElementsByName()的用法说明
2009/07/31 Javascript
复制小说文本时出现的随机乱码的去除方法
2010/09/07 Javascript
判断用户的在线状态 onbeforeunload事件
2011/03/05 Javascript
jQuery简单实现遍历数组的方法
2015/04/14 Javascript
JavaScript实现的伸展收缩型菜单代码
2015/10/14 Javascript
JS数组返回去重后数据的方法解析
2017/01/03 Javascript
vue快捷键与基础指令详解
2017/06/01 Javascript
基于jQuery中ajax的相关方法汇总(必看篇)
2017/11/08 jQuery
基于vue-cli创建的项目的目录结构及说明介绍
2017/11/23 Javascript
[06:07]DOTA2-DPC中国联赛 正赛 Ehome vs VG 选手采访
2021/03/11 DOTA
python处理PHP数组文本文件实例
2014/09/18 Python
构建Python包的五个简单准则简介
2015/06/15 Python
python不换行之end=与逗号的意思及用途
2017/11/21 Python
详解Python中的正则表达式
2018/07/08 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
Python动态导入模块和反射机制详解
2020/02/18 Python
python算的上脚本语言吗
2020/06/22 Python
详解pycharm配置python解释器的问题
2020/10/15 Python
Python爬虫入门教程02之笔趣阁小说爬取
2021/01/24 Python
canvas绘图按照contain或者cover方式适配并居中显示
2019/02/18 HTML / CSS
法学研究生自我鉴定范文
2013/12/04 职场文书
小学课外阅读总结
2014/07/09 职场文书
后备干部推荐材料
2014/12/24 职场文书
社区环境卫生倡议书
2015/04/29 职场文书
农民工工资保障承诺书
2015/05/04 职场文书
小学教师教育随笔
2015/08/14 职场文书
学习型家庭事迹材料(2016精选版)
2016/02/29 职场文书
廉政党课工作报告案例
2019/06/21 职场文书
python基于opencv批量生成验证码的示例
2021/04/28 Python
mybatis调用sqlserver存储过程返回结果集的方法
2021/05/08 SQL Server
python flask框架快速入门
2021/05/14 Python