python數學建模之Numpy 應用介紹與Pandas學習
Numpy學習
1 Numpy 介紹與應用
1-1Numpy是什麼
NumPy 是一個運行速度非常快的數學庫,一個開源的的python科學計算庫,主要用於數組、矩陣計算,包含:
一個強大的N維數組對象 ndarray廣播功能函數整合 C/C++/Fortran 代碼的工具線性代數、傅裡葉變換、隨機數生成等功能 1-2 為什麼選擇Numpy
對於同樣的數值計算任務,使用Numpy比直接編寫原生python代碼的優點有:
代碼更簡潔:
Numpy直接以數組、矩陣為粒度計算並且支撐大量的數學函數,而Python需要用for循環從底層實現
性能更高效:
Numpy的數組存儲效率和輸入輸出計算性能,比Python使用List或者嵌套List好很多
註意:Numpy的數據存儲和Python原生的List是不一樣的
加上Numpy的大部分代碼都是C語言實現的,這是Numpy比純Python代碼高效的原因
相關學習、代碼如下:須提前安裝好Numpy、pandas和matplotlib
Numpy終端安裝命令:pip install numpy
Pandas終端安裝命令:pip install pandas
Matplotlib終端安裝過命令:pip install matplotlib
# @Software : PyCharm # Numpy是Python各種數據科學類庫的基礎庫 # 比如:Pandas,Scipy,Scikit_Learn等 # Numpy應用: ''' NumPy 通常與 SciPy(Scientific Python)和 Matplotlib(繪圖庫)一起使用, 這種組合廣泛用於替代 MatLab,是一個強大的科學計算環境,有助於我們通過 Python 學習數據科學或者機器學習。 SciPy 是一個開源的 Python 算法庫和數學工具包。 SciPy 包含的模塊有最優化、線性代數、積分、插值、特殊函數、快速傅裡葉變換、信號處理和圖像處理、常微分方程求解和其他科學與工程中常用的計算。 Matplotlib 是 Python 編程語言及其數值數學擴展包 NumPy 的可視化操作界面。它為利用通用的圖形用戶界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向應用程序嵌入式繪圖提供瞭應用程序接口(API)。 ''' # 安裝 NumPy 最簡單的方法就是使用 pip 工具: # pip3 install --user numpy scipy matplotlib # --user 選項可以設置隻安裝在當前的用戶下,而不是寫入到系統目錄。 # 默認情況使用國外線路,國外太慢,我們使用清華的鏡像就可以: # pip install numpy scipy matplotlib -i.csv https://pypi.tuna.tsinghua.edu.cn/simple # 這種pip安裝是一種最簡單、最輕量級的方法,當然,這裡的前提是有Python包管理器 # 如若不行,可以安裝Anaconda【目前應用較廣泛】,這是一個開源的Python發行版 # 安裝Anaconda地址:https://www.anaconda.com/ # 安裝驗證 # 測試是否安裝成功 from numpy import * # 導入 numpy 庫 print(eye(4)) # 生成對角矩陣 # 查看版本: import numpy as np print(np.__version__) # 實現2個數組的加法: # 1-原生Python實現 def Py_sum(n): a = [i**2 for i in range(n)] b = [i**3 for i in range(n)] # 創建一個空列表,便於後續存儲 ab_sum = [] for i in range(n): # 將a、b中對應的元素相加 ab_sum.append(a[i]+b[i]) return ab_sum # 調用實現函數 print(Py_sum(10)) # 2-Numpy實現: def np_sum(n): c = np.arange(n) ** 2 d = np.arange(n) ** 3 return c+d print(np_sum(10)) # 易看出使用Numpy代碼簡潔且運行效率快 # 測試1000,10W,以及100W的運行時間 # 做繪圖對比: import pandas as pd # 輸入數據 py_times = [1.72*1000, 202*1000, 1.92*1000] np_times = [18.8, 14.9*1000, 17.8*10000] # 創建Pandas的DataFrame類型數據 ch_lxw = pd.DataFrame({ 'py_times': py_times, 'np_times': np_times # 可加逗號 }) print(ch_lxw)
import matplotlib.pyplot as plt # 線性圖 print(ch_lxw.plot()) # 柱狀圖 print(ch_lxw.plot.bar()) # 簡易箱線圖 print(ch_lxw.boxplot) plt.show()
線性圖運行效果如下:
柱狀圖運行效果如下:
2 NumPy Ndarray 對象
NumPy 最重要的一個特點是其 N 維數組對象 ndarray,它是一系列同類型數據的集合,以 0 下標為開始進行集合中元素的索引。
ndarray 對象是用於存放同類型元素的多維數組,其中的每個元素在內存中都有相同存儲大小的區域。ndarray 對象采用瞭數組的索引機制,將數組中的每個元素映射到內存塊上,並且按照一定的佈局對內存塊進行排序(行或列)
ndarray 內部由以下內容組成:
- 一個指向數據(內存或內存映射文件中的一塊數據)的指針;
- 數據類型或 dtype,描述在數組中的固定大小值的格子;
- 一個表示數組形狀(shape)的元組,表示各維度大小的元組;
- 一個跨度元組(stride),其中的整數指的是為瞭前進到當前維度下一個元素需要"跨過"的字節數。
相關學習、代碼如下:
''' 創建一個 ndarray 隻需調用 NumPy 的 array 函數即可: numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0) 參數說明: 名稱 描述 object 表示數組或嵌套的數列 dtype 表示數組元素的數據類型,可選 copy 表示對象是否需要復制,可選 order 創建數組的樣式,C為行方向,F為列方向,A為任意方向(默認) subok 默認返回一個與基類類型一致的數組 ndmin 指定生成數組的最小維度 ''' # ndarray 對象由計算機內存的連續一維部分組成,並結合索引模式,將每個元素映射到內存塊中的一個位置。 # 內存塊以行順序(C樣式)或列順序(FORTRAN或MatLab風格,即前述的F樣式)來保存元素 # 學好Numpy,便於後期對Pandas的數據處理 # 1:一維 import numpy as np lxw = np.array([5, 2, 0]) print(lxw) print() # 2: 多於一個維度 import numpy as np lxw2 = np.array([[1, 5, 9], [5, 2, 0]]) print(lxw2) print() # 3: 最小維度 import numpy as np lxw3 = np.array([5, 2, 0, 1, 3, 1, 4], ndmin=2) # ndmin: 指定生成數組的最小維度 print(lxw3) print() # 4: dtype參數 import numpy as np lxw4 = np.array([3, 3, 4, 4], dtype=complex) # dtype: 數組元素的數據類型[complex 復數】 print(lxw4)
3 Numpy 數據類型
numpy 支持的數據類型比 Python 內置的類型要多很多,基本上可以和 C 語言的數據類型對應上,其中部分類型對應為 Python 內置的類型.
常用 NumPy 基本類型:
名稱 描述
bool_ :【佈爾型數據類型(True 或者 False)】
int_ : 【默認的整數類型(類似於 C 語言中的 long,int32 或 int64)】
intc :【與 C 的 int 類型一樣,一般是 int32 或 int 64】
intp :【用於索引的整數類型(類似於 C 的 ssize_t,一般情況下仍然是 int32 或 int64)】
int8 :【字節(-128 to 127)】
int16 :【整數(-32768 to 32767)】
int32 :【整數(-2147483648 to 2147483647)】
int64 :【整數(-9223372036854775808 to 9223372036854775807)】
uint8 :【無符號整數(0 to 255)】
uint16 :【無符號整數(0 to 65535)】
uint32 :【無符號整數(0 to 4294967295)】
uint64 :【無符號整數(0 to 18446744073709551615)】
float_ float64 :【類型的簡寫】
float16 :【半精度浮點數,包括:1 個符號位,5 個指數位,10 個尾數位】
float32 :【單精度浮點數,包括:1 個符號位,8 個指數位,23 個尾數位】
float64 :【雙精度浮點數,包括:1 個符號位,11 個指數位,52 個尾數位】
complex_ complex128: 【類型的簡寫,即 128 位復數】
complex64 :【復數,表示雙 32 位浮點數(實數部分和虛數部分)】
complex128 :【復數,表示雙 64 位浮點數(實數部分和虛數部分)】
相關學習、代碼如下:
''' # numpy 的數值類型實際上是 dtype 對象的實例,並對應唯一的字符,包括 np.bool_,np.int32,np.float32,等等。 ''' # Numpy 類型對象: ''' dtype 對象是使用以下語法構造的: numpy.dtype(object, align, copy) object - 要轉換為的數據類型對象 align - 如果為 true,填充字段使其類似 C 的結構體。 copy - 復制 dtype 對象 ,如果為 false,則是對內置數據類型對象的引用 ''' # 1: 使用標量類型 import numpy as np lxw = np.dtype(np.int32) print(lxw) print() # 2: int8, int16, int32, int64 四種數據類型可以使用字符串 'i1', 'i2','i4','i8' 代替 import numpy as np lxw2 = np.dtype('i8') # int64 print(lxw2) print() # 3: 字節順序標註 import numpy as np lxw3 = np.dtype('<i4') # int32 print(lxw3) print() # 4: 首先創建結構化數據類型 import numpy as np lxw4 = np.dtype([('age', np.int8)]) # i1 print(lxw4) print() # 5: 將數據類型應用於 ndarray 對象 import numpy as np lxw5 = np.dtype([('age', np.int32)]) a = np.array([(10,), (20,), (30,)], dtype=lxw5) print(a) print() # 6: 類型字段名可以用於存取實際的 age 列 import numpy as np lxw6 = np.dtype([('age', np.int64)]) a = np.array([(10,), (20,), (30,)], dtype=lxw6) print(a['age']) print() # 7: 定義一個結構化數據類型 student,包含字符串字段 name,整數字段 age,及浮點字段 marks,並將這個 dtype 應用到 ndarray 對象 import numpy as np student = np.dtype([('name', 'S20'), ('age', 'i2'), ('marks', 'f4')]) print(student) # 運行結果:[('name', 'S20'), ('age', '<i2'), ('marks', '<f4')] print() # 8: import numpy as np student2 = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')]) lxw = np.array([('lxw', 21, 52), ('cw', 22, 58)], dtype=student2) print(lxw) # 運行結果:[(b'lxw', 21, 52.) (b'cw', 22, 58.)] # 每個內建類型都有一個唯一定義它的字符代碼,如下: ''' 字符 對應類型 b 佈爾型 i.csv (有符號) 整型 u 無符號整型 integer f 浮點型 c 復數浮點型 m timedelta(時間間隔) M datetime(日期時間) O (Python) 對象 S, a (byte-)字符串 U Unicode V 原始數據 (void) '''
4 Numpy 數組屬性
在 NumPy中,每一個線性的數組稱為是一個軸(axis),也就是維度(dimensions)。
比如說,二維數組相當於是兩個一維數組,其中第一個一維數組中每個元素又是一個一維數組。
相關代碼學習、如下:
# NumPy 的數組中比較重要 ndarray 對象屬性有: ''' 屬性 說明 ndarray.ndim 秩,即軸的數量或維度的數量 ndarray.shape 數組的維度,對於矩陣,n 行 m 列 ndarray.size 數組元素的總個數,相當於 .shape 中 n*m 的值 ndarray.dtype ndarray 對象的元素類型 ndarray.itemsize ndarray 對象中每個元素的大小,以字節為單位 ndarray.flags ndarray 對象的內存信息 ndarray.real ndarray元素的實部 ndarray.imag ndarray 元素的虛部 ndarray.data 包含實際數組元素的緩沖區,由於一般通過數組的索引獲取元素,所以通常不需要使用這個屬性。 ''' # ndarray.ndim # ndarray.ndim 用於返回數組的維數,等於秩。 import numpy as np lxw = np.arange(36) print(lxw.ndim) # a 現隻有一個維度 # 現調整其大小 a = lxw.reshape(2, 6, 3) # 現在擁有三個維度 print(a.ndim) print() # ndarray.shape # ndarray.shape 表示數組的維度,返回一個元組,這個元組的長度就是維度的數目,即 ndim 屬性(秩)。比如,一個二維數組,其維度表示"行數"和"列數"。 # ndarray.shape 也可以用於調整數組大小。 import numpy as np lxw2 = np.array([[169, 175, 165], [52, 55, 50]]) print(lxw2.shape) # shape: 數組的維度 print() # 調整數組大小: import numpy as np lxw3 = np.array([[123, 234, 345], [456, 567, 789]]) lxw3.shape = (3, 2) print(lxw3) print() # NumPy 也提供瞭 reshape 函數來調整數組大小: import numpy as np lxw4 = np.array([[23, 543, 65], [32, 54, 76]]) c = lxw4.reshape(2, 3) # reshape: 調整數組大小 print(c) print() # ndarray.itemsize # ndarray.itemsize 以字節的形式返回數組中每一個元素的大小。 # 例如,一個元素類型為 float64 的數組 itemsize 屬性值為 8(float64 占用 64 個 bits, # 每個字節長度為 8,所以 64/8,占用 8 個字節),又如,一個元素類型為 complex32 的數組 item 屬性為 4(32/8) import numpy as np # 數組的 dtype 為 int8(一個字節) x = np.array([1, 2, 3, 4, 5], dtype=np.int8) print(x.itemsize) # 數組的dtypy現在為float64(八個字節) y = np.array([1, 2, 3, 4, 5], dtype=np.float64) print(y.itemsize) # itemsize: 占用字節個數 # 拓展: # 整體轉化為整數型 print(np.array([3.5, 6.6, 8.9], dtype=int)) # 設置copy參數,默認為True a = np.array([2, 5, 6, 8, 9]) b = np.array(a) # 復制a print(b) # 控制臺打印b print(f'a: {id(a)}, b: {id(b)}') # 可打印出a和b的內存地址 print('='*20) # 類似於列表的引用賦值 b = a print(f'a: {id(a)}, b: {id(b)}') # 創建一個矩陣 lxw5 = np.mat([1, 2, 3, 4, 5]) print(type(lxw5)) # 矩陣類型: <class 'numpy.matrix'> # 復制出副本,並保持原類型 yy = np.array(lxw5, subok=True) print(type(yy)) # 隻復制副本,不管其類型 by = np.array(lxw5, subok=False) # False: 使用數組的數據類型 print(type(by)) print(id(yy), id(by)) print('='*20) # 使用數組的copy()方法: c = np.array([2, 5, 6, 2]) cp = c.copy() print(id(c), id(cp)) print() # ndarray.flags ''' ndarray.flags 返回 ndarray 對象的內存信息,包含以下屬性: 屬性 描述 C_CONTIGUOUS (C) 數據是在一個單一的C風格的連續段中 F_CONTIGUOUS (F) 數據是在一個單一的Fortran風格的連續段中 OWNDATA (O) 數組擁有它所使用的內存或從另一個對象中借用它 WRITEABLE (W) 數據區域可以被寫入,將該值設置為 False,則數據為隻讀 ALIGNED (A) 數據和所有元素都適當地對齊到硬件上 UPDATEIFCOPY (U) 這個數組是其它數組的一個副本,當這個數組被釋放時,原數組的內容將被更新 ''' import numpy as np lxw4 = np.array([1, 3, 5, 6, 7]) print(lxw4.flags) # flags: 其內存信息
Pandas學習
當然,做這些的前提是首先把文件準備好
文件準備:
文件太長,故隻截取瞭部分,當然,此文件可自行弄類似的也可以!
1 pandas新增數據列
在進行數據分析時,經常需要按照一定條件創造新的數據列,然後再進一步分析
- 直接賦值
- df.apply()方法
- df.assign()方法
- 按條件進行分組分別賦值
# 1: import pandas as pd # 讀取數據 lxw = pd.read_csv('sites.csv') # print(lxw.head()) df = pd.DataFrame(lxw) # print(df) df['lrl'] = df['lrl'].map(lambda x: x.rstrip('%')) # print(df) df.loc[:, 'jf'] = df['yye'] - df['sku_cost_prc'] # 返回的是Series # print(df.head()) # 2: def get_cha(n): if n['yye'] > 5: return '高價' elif n['yye'] < 2: return '低價' else: return '正常價' df.loc[:, 'yye_type'] = df.apply(get_cha, axis=1) # print(df.head()) print(df['yye_type'].value_counts()) # 3: # 可同時添加多個新列 print(df.assign( yye_bh=lambda x: x['yye']*2-3, sl_zj=lambda x: x['sku_cnt']*6 ).head(10)) # 4: # 按條件先選擇數據,然後對這部分數據賦值新列 # 先創建空列 df['zyye_type'] = '' df.loc[df['yye'] - df['sku_cnt']>8, 'zyye_type'] = '高' df.loc[df['yye'] - df['sku_cnt'] <= 8, 'zyye_type'] = '低' print(df.head())
下面分別是每個小問對應運行效果:
1:
2:
3:
4:
2 Pandas數據統計函數
# Pandas數據統計函數 ''' 1-匯總類統計 2-唯一去重和按值計數 3-相關系數和協方差 ''' import pandas as pd lxw = pd.read_csv('nba.csv') # print(lxw.head(3)) # 1: # 一下子提取所有數字列統計結果 print(lxw.describe()) # 查看單個Series的數據 print(lxw['Age'].mean()) # 年齡最大 print(lxw['Age'].max()) # 體重最輕 print(lxw['Weight'].min()) # 2: # 2-1 唯一性去重【一般不用於數值項,而是枚舉、分類項】 print(lxw['Height'].unique()) print(lxw['Team'].unique()) # 2-2 按值計算 print(lxw['Age'].value_counts()) print(lxw['Team'].value_counts()) # 3: # 應用:股票漲跌、產品銷量波動等等 ''' 對於兩個變量X、Y: 1-協方差:衡量同向程度程度,如果協方差為正,說明X、Y同向變化,協方差越大說明同向程度越高; 如果協方差為負,說明X、Y反向運動,協方差越小說明方向程度越高。 2-相關系數:衡量相似度程度,當他們的相關系數為1時,說明兩個變量變化時的正向相似度最大, 當相關系數為-1,說明兩個變化時的反向相似度最大。 ''' # 協方差矩陣: print(lxw.cov()) # 相關系數矩陣: print(lxw.corr()) # 單獨查看年齡和體重的相關系數 print(lxw['Age'].corr(lxw['Weight'])) # Age和Salary的相關系數 print(lxw['Age'].corr(lxw['Salary'])) # 註意看括號內的相減 print(lxw['Age'].corr(lxw['Salary']-lxw['Weight']))
1:
2-1:
部分2-2:
3:
3 Pandas對缺失值的處理
特殊Excel的讀取、清洗、處理:
# Pandas對缺失值的處理 ''' 函數用法: 1-isnull和notnull: 檢測是否有控制,可用於dataframe和series 2-dropna: 丟棄、刪除缺失值 2-1 axis: 刪除行還是列,{0 or 'index', 1 or 'columns'}, default() 2-2 how: 如果等於any, 則任何值都為空,都刪除;如果等於all所有值都為空,才刪除 2-3 inplace: 如果為True,則修改當前dataframe,否則返回新的dataframe 2-4 value: 用於填充的值,可以是單個值,或者字典(key是列名,value是值) 2-5 method: 等於ffill使用前一個不為空的值填充forword fill;等於bfill使用後一個不為空的值填充backword fill 2-6 axis: 按行還是按列填充,{0 or "index", 1 or "columns"} 2-7 inplace: 如果為True則修改當前dataframe,否則返回新的dataframe ''' # 特殊Excel的讀取、清洗、處理 import pandas as pd # 1: 讀取excel時,忽略前幾個空行 stu = pd.read_excel("Score表.xlsx", skiprows=14) # skiprows: 控制在幾行以下 print(stu) # 2: 檢測空值 print(stu.isnull()) print(stu['成績'].isnull()) print(stu['成績'].notnull()) # 篩選沒有空成績的所有行 print(stu.loc[stu['成績'].notnull(), :]) # 3: 刪除全是空值的列: # axis: 刪除行還是列,{0 or 'index', 1 or 'columns'}, default() # how: 如果等於any, 則任何值都為空,都刪除;如果等於all所有值都為空,才刪除 # inplace: 如果為True則修改當前dataframe,否則返回新的dataframe stu.dropna(axis="columns", how="all", inplace=True) print(stu) # 4: 刪除全是空值的行: stu.dropna(axis="index", how="all", inplace=True) print(stu) # 5: 將成績列為空的填充為0分: stu.fillna({"成績": 0}) print(stu) # 同上: stu.loc[:, '成績'] = stu['成績'].fillna(0) print(stu) # 6: 將姓名的缺失值填充【使用前面的有效值填充,用ffill: forward fill】 stu.loc[:, '姓名'] = stu['姓名'].fillna(method='ffill') print(stu) # 7: 將清洗好的Excel保存: stu.to_excel("Score成績_clean.xlsx", index=False)
1:
2
3:
4:
5:
6:
總結
今天我學習瞭處理python數據分析的另一個庫——Numpy,剛開始接觸這個庫的時候真的感覺沒什麼意思,可學的越深入一點,越覺得越有意思,當然,昨天的那個庫也挺不錯的,主要是Numpy這個是學Pandas的基礎,得打好基礎,當然也不會落下Pandas的學習!
到此這篇關於python數學建模之Numpy 應用介紹與Pandas學習的文章就介紹到這瞭,更多相關python Numpy 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python Numpy中ndarray的常見操作
- NumPy-ndarray 的數據類型用法說明
- python數學建模是加深Numpy和Pandas學習
- Python數據分析之Numpy庫的使用詳解
- 聊聊Numpy.array中[:]和[::]的區別在哪