浅谈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中datetime常用时间处理方法
Jun 15 Python
Python中使用OpenCV库来进行简单的气象学遥感影像计算
Feb 19 Python
Python中文分词实现方法(安装pymmseg)
Jun 14 Python
Python DataFrame一列拆成多列以及一行拆成多行
Aug 06 Python
详解用python计算阶乘的几种方法
Aug 14 Python
python字符串格式化方式解析
Oct 19 Python
wxpython绘制音频效果
Nov 18 Python
Python + Requests + Unittest接口自动化测试实例分析
Dec 12 Python
python filecmp.dircmp实现递归比对两个目录的方法
May 22 Python
Python中Pyspider爬虫框架的基本使用详解
Jan 27 Python
django 认证类配置实现
Nov 11 Python
分享Python获取本机IP地址的几种方法
Mar 17 Python
python四种出行路线规划的实现
浅谈Python数学建模之线性规划
Jun 23 #Python
教你如何用Python实现人脸识别(含源代码)
python 对图片进行简单的处理
DjangoRestFramework 使用 simpleJWT 登陆认证完整记录
浅析Python中的套接字编程
Python中使用ipython的详细教程
You might like
PHP安装问题
2006/10/09 PHP
php smarty的预保留变量总结
2008/12/04 PHP
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
PHP学习笔记(三):数据类型转换与常量介绍
2015/04/17 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
2018/04/20 PHP
ext combox 下拉框不出现自动提示,自动选中的解决方法
2010/02/24 Javascript
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
IE的fireEvent方法概述及应用
2013/02/22 Javascript
JavaScript获取图片的原始尺寸以宽度为例
2014/05/04 Javascript
node.js中的fs.readdirSync方法使用说明
2014/12/17 Javascript
js+cookies实现悬浮购物车的方法
2015/05/25 Javascript
JavaScript位移运算符(无符号) &gt;&gt;&gt; 三个大于号 的使用方法详解
2016/03/31 Javascript
JS中type=&quot;button&quot;和type=&quot;submit&quot;的区别
2017/07/04 Javascript
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
2017/09/12 Javascript
node.js博客项目开发手记
2018/03/16 Javascript
手把手教你 CKEDITOR 4 实现Dialog 内嵌 IFrame操作详解
2019/06/18 Javascript
如何用vue-cli3脚手架搭建一个基于ts的基础脚手架的方法
2019/12/12 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
基于vue+echarts数据可视化大屏展示的实现
2020/12/25 Vue.js
python中字典dict常用操作方法实例总结
2015/04/04 Python
浅谈python 里面的单下划线与双下划线的区别
2017/12/01 Python
django项目搭建与Session使用详解
2018/10/10 Python
Python @property使用方法解析
2019/09/17 Python
Python字典底层实现原理详解
2019/12/18 Python
CSS3制作炫酷的下拉菜单及弹起式选单的实例分享
2016/05/17 HTML / CSS
html5 更新图片颜色示例代码
2014/07/29 HTML / CSS
canvas与html5实现视频截图功能示例
2016/12/15 HTML / CSS
AmazeUI框架搭建的方法步骤(图文)
2020/08/17 HTML / CSS
澳洲的UGG雪地靴超级市场:Uggs.com.au
2020/04/06 全球购物
新年寄语大全
2014/04/12 职场文书
小班上学期评语
2014/05/05 职场文书
十八大演讲稿
2014/05/22 职场文书
如何写股份合作协议书
2014/09/11 职场文书
家庭经济困难证明
2015/06/23 职场文书
基于JavaScript实现省市联动效果
2021/06/22 Javascript
react 路由Link配置详解
2021/11/11 Javascript