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

526

# @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()

線性圖運行效果如下:

63

柱狀圖運行效果如下:

528

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!

推薦閱讀: