Python小白的數學建模課-02.數據導入


數據導入是全部數模編程的第一步,比你想象的更重要。html

先要學會一種未必最佳,可是通用、安全、簡單、好學的方法。python

『Python小白的數學建模課 @ Youcans』帶你從數模小白成爲國賽達人。算法



1. 數據導入是全部數模編程的第一步

編程求解一個數模問題,問題總會涉及一些數據。sql

有些數據是在題目的文字描述中給出的,有些數據是經過題目的附件文件下載或指定網址提供的,還有些數據是須要本身蒐集的。不管是哪一種方式得到的數據,也不論哪一種類型的問題和算法,首先都是要把這些數據以適當的方式和格式導入到程序中。數據庫

若是數據格式有問題,輕則讀取數據時發生錯誤,要浪費時間去查找和解決,在數模競賽中就會讓人很是焦躁。數據錯誤仍是輕的嗎?對,重則讀取數據有錯誤,程序卻在繼續運行,獲得了錯誤的結果,這在數模競賽中就更糟糕了。你可能都不知道發生了錯誤,就算感受有問題也不會把錯誤直接鎖定到數據導入部分,結果不停地去修改其它模塊,直到把正確的模塊也搞錯了,最後無可救藥。編程

所以,確保數模編程第一步「數據導入」的順利完成,比原先的想象更重要。json

Python 語言中數據導入的方法不少。對於數學建模問題編程來講,選擇什麼方法最好呢?答案是:沒有最好的,只有最合適的。對於不一樣的問題,不一樣的算法,以及所調用工具包的不一樣實現方法,對於數據就會有不一樣的要求。另外,賽題所給數據文件中的數據組織方式不一樣,也須要使用不一樣的方法來導入數據。安全

那麼好了,既然是要具體問題具體分析,這不跟沒說同樣嗎?這正是本文但願回答的問題,雖然針對不一樣問題的最佳的數據導入方法也不一樣,但咱們先要學會一種未必最佳,可是通用、安全、簡單、好學的方法。數據結構


歡迎關注 『Python小白的數學建模課 @ Youcans』,每週更新數模筆記
Python小白的數學建模課-01.新手必讀
Python小白的數學建模課-02.數據導入
Python小白的數學建模課-03.線性規劃
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計迴歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法模塊化




2. 在程序中直接向變量賦值

直接在程序中向變量賦值,是雖然笨拙但最簡單的方法,也許仍是最可靠的方法——若是你沒有敲錯鍵盤的話。

確實,把直接賦值做爲數據導入方法來介紹,實在是很差意思說出口。可是,對於數模競賽這種特殊的需求,直接賦值的方法仍是十分經常使用的,並且徹底符合簡單、實用、可靠的要求。

不過,直接賦值也並不是咱們想的那麼簡單,仍是值得認真地談一談。

2.1 爲何直接賦值?

絕大部分數學建模教材中的例程,都是使用直接賦值的方法導入數據。很大比例的博客例程,包括本系列的大多數案例,也都是在程序中直接賦值的。

其緣由在於,一是爲了保證程序的完整性,複製粘貼回車就能獲得運行結果,不須要複製數據文件等操做,就避免了由此引發的各類錯誤;二是爲了把讀者的注意力聚焦在主要的知識點,避免干擾;三是使例程更加直觀易懂,便於理解例程的算法。

這些緣由也都是直接賦值的優勢。那麼,這些優勢不也正是數模競賽編程活動的痛點嗎?沒錯,這就是直接賦值方法在數學建模培訓和數模競賽編程的實踐中普遍流行的緣由。

2.2 直接賦值的問題與注意事項

可是,即便在數模競賽編程中,直接賦值也會有幾個問題。

一是某些問題不能使用直接賦值方法。這主要是大數據的問題,數據量或數據文件的數量極大,已經不能使用直接賦值實現了。

二是一些問題雖然能夠直接賦值,但很容易出錯。這主要是數據量很大,或者數據結構、類型比較複雜的問題。

例如,多元分析、時間序列、數據統計類的題目可能都有很大的數據量,在附件中提供數據文件。這時若是在使用直接賦值導入數據,再也不是敲鍵盤了,而是從文件中把數據複製粘貼到程序中。

這時要特別注意的問題是:

  1. 文件中的數據分隔符是什麼,空格仍是逗號,與變量賦值的格式要求是否一致?
  2. 即便文件中的數據分隔符看上去是空格,也須要檢查究竟是空格仍是製表符,是一個空格仍是幾個空格?
  3. 文件中的數據有沒有錯漏等異常?這在讀取文件中能夠經過程序檢查、識別和處理,在複製粘貼時就要人工處理了。

三是數據量不大的問題,徹底能夠用直接賦值導入數據,但也會因爲疏忽大意而出錯。

這倒不是說敲錯鍵盤了,而是因爲例程不必定是把數據賦值做爲獨立模塊處理的,而是分散在算法的過程當中進行賦值。同窗在使用和修改例程時時,就很容易忘記修改算法過程當中的變量賦值。這種狀況家常便飯,有時是由於對程序沒有搞明白,忽略了算法步驟中的某個變量;更多時候是忙中出錯,在反覆調試和更換數據時暈頭轉向,只顧了修改開始的數據而疏忽了後面的數據。

養成數據導入模塊化的習慣,才能避免這一類的疏忽:

  1. 將數據導入模塊做爲單獨的函數。
  2. 若是不肯意使用數據導入函數,則要把數據導入部分集中寫成一段,放在程序的起始部分。
  3. 不要把問題自己的數據導入與算法所需的參數賦值混淆,分爲兩個獨立的函數或段落。

例程 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)


3. Pandas 導入數據

雖然不少數模競賽的問題能夠經過直接賦值獲取數據,但主流的數據導入方法仍是讀取數據文件。

數學建模中經常使用的數據文件格式有文本文件(.txt)、Excel 文件(.xls, .xlsx)和 csv 文件(.csv)。

在讀取文本文件時,會遇到逗號、空格、製表符等不一樣的數據分割符。讀取 Excel 文件時,首先 .xls 與 .xlsx 的格式不一樣,其次要考慮數據錶帶不帶標題行,有時文件中還有多個工做表。讀取文件時還會遇到數據缺失,非法字符。對於小白來講,特別在競賽時,處理這些問題時都會心神不寧。

Python 中讀取數據文件的方法也不少。本文很是不推薦使用 Python 自身的文件操做如打開(open)、關閉(close)、讀寫(read、readline)函數,而是推薦使用 Pandas 讀取數據文件。緣由在於:

  1. Pandas 提供了多種經常使用文件格式的讀寫函數,以上各類狀況都能一行代碼搞定。
  2. Pandas 是基於 NumPy 構建的數據分析工具包,便於進行數據整理與清洗,操做方便靈活。
  3. Pandas 提供了與其它各類數據結構的轉換工具,使用簡單靈活。
  4. 不少數學建模算法的例程就是使用 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_table( 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 進行處理,這將在後續文章結合具體問題進行講解。



4. 數據導入例程

【重要說明】以上章節的內容雖然介紹了數據導入的基本方法,但恐怕仍是難以達到消化吸取,爲我所用。爲了解決這個問題,本文將相關內容整合爲例程,以便於讀者學習收藏,也便於使用修改。

例程01:讀取數據文件

# mathmodel01_v1.py
# Demo01 of mathematical modeling algorithm
# Read data files into DataFrame.
# Copyright 2021 Youcans, XUPT
# Crated:2021-05-27

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小白的數學建模課 @ Youcans』 原創做品

原創做品,轉載必須標註原文連接(https://www.cnblogs.com/youcans/p/14827163.html)。

Copyright 2021 Youcans, XUPT

Crated:2021-05-27


歡迎關注 『Python小白的數學建模課 @ Youcans』,每週更新數模筆記
Python小白的數學建模課-01.新手必讀
Python小白的數學建模課-02.數據導入
Python小白的數學建模課-03.線性規劃
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計迴歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法

相關文章
相關標籤/搜索