Python使用NumPy創(chuàng)建數(shù)組的完全指南
六月的風(fēng)帶著點甜味,朋友圈被各種童真刷屏。趁著這個萬物皆可"玩"的季節(jié),咱們也來玩點硬核的——用NumPy搭積木。說真的,NumPy的數(shù)組和樂高沒什么本質(zhì)區(qū)別:都是用最簡單的單元,拼出你想得到的一切。
為什么要學(xué)NumPy?
如果把機(jī)器學(xué)習(xí)比作精彩的冒險旅程,那 NumPy 就是出發(fā)前必學(xué)的基礎(chǔ)技能課,缺一不可。
寫Python處理數(shù)據(jù),你大概率會遇到這行"神咒":
import numpy as np
為什么繞不開它?兩個字:快和簡。
- 向量化運(yùn)算:告別for循環(huán),一行代碼干完十行的活
- 廣播機(jī)制:形狀不同的數(shù)組也能直接算,Python原生列表做不到
今天這篇,從數(shù)組創(chuàng)建到變形運(yùn)算,一次性把NumPy的基礎(chǔ)打扎實——地基穩(wěn)了,后面蓋樓才不慌。
一、np.array:從列表到數(shù)組,一步之遙
最直覺的方式,把一個Python列表扔進(jìn)去:
arr = np.array([1, 2, 3]) print(arr) # [1 2 3]
等等,Python列表[1, 2, 3]不也能用嗎?為什么要多此一舉?
因為它們壓根不是一回事:
| Python列表 | NumPy數(shù)組 | |
|---|---|---|
| 類型 | 來者不拒,int、str、dict混著裝 | 認(rèn)死理,一個數(shù)組只認(rèn)一種類型 |
| 運(yùn)算 | [1,2]+[3,4] → [1,2,3,4](拼接) | np.array([1,2])+np.array([3,4]) → [4 6](逐元素加) |
| 速度 | 循環(huán)處理,慢 | 底層C實現(xiàn),快到飛起 |
# Python列表:+ 是拼接 [1, 2, 3] + [4, 5, 6] # [1, 2, 3, 4, 5, 6] # NumPy數(shù)組:+ 是數(shù)學(xué)運(yùn)算 np.array([1, 2, 3]) + np.array([4, 5, 6]) # [5 7 9]
一個管"裝東西",一個管"算東西"。功能不同,別混為一談。
二、嵌套列表:給積木加個維度
一維數(shù)組是條線,二維是張表,三維就是個箱子。用嵌套列表可以一層層搭上去:
list1 = [list(range(i, i+3)) for i in [2, 4, 6]] print(list1) # [[2, 3, 4], [6, 7, 8], [10, 11, 12]] c = np.array([range(i, i+3) for i in [2, 4, 6]]) print(c) # [[ 2 3 4] # [ 6 7 8] # [10 11 12]]
每一層列表就是積木的一層,疊起來就成了立體結(jié)構(gòu)。道理就這么樸素。
三、快速創(chuàng)建:NumPy的"模板工廠"
有些數(shù)組不需要你一個個填值——全0、全1、等差數(shù)列,NumPy早就幫你備好了模板。
np.zeros:全0數(shù)組
nz = np.zeros(10, dtype=int) print(nz) # [0 0 0 0 0 0 0 0 0 0]
十個零,整整齊齊。dtype=int讓它輸出整數(shù)而不是浮點數(shù)。
np.ones:全1數(shù)組
no = np.ones((3, 5)) print(no) # [[1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.] # [1. 1. 1. 1. 1.]]
3行5列,默認(rèn)浮點型(1.不是1)。需要整型就加dtype=int。
np.arange:等差數(shù)列
和Python的range是親兄弟,但直接返回NumPy數(shù)組:
na = np.arange(0, 20, 2) print(na) # [ 0 2 4 6 8 10 12 14 16 18]
對比一下:
list(range(0, 20, 2)) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] ← 列表 np.arange(0, 20, 2) # [ 0 2 4 6 8 10 12 14 16 18] ← 數(shù)組
長得像,但底層完全不同。一個是Python對象,一個是NumPy的連續(xù)內(nèi)存塊。
四、隨機(jī)數(shù)組:開盲盒時間
隨機(jī)數(shù)是NumPy里最好玩的部分——你永遠(yuǎn)不知道下一個數(shù)是什么(除非你設(shè)了種子)。
基礎(chǔ)隨機(jī)
a1 = np.random.random() # 一個[0,1)的隨機(jī)浮點數(shù) a2 = np.random.random(1) # 包含一個元素的數(shù)組 a3 = np.random.random((3, 3)) # 3×3的隨機(jī)數(shù)組 a4 = np.random.random((2, 3, 4)) # 2層×3行×4列,三維隨機(jī)數(shù)組
指定范圍
a5 = np.random.uniform(5, 7, (2, 2)) # [5,7)之間的隨機(jī)浮點,2×2 a6 = np.random.randint(5, 7, (2, 2)) # [5,7)之間的隨機(jī)整數(shù),2×2
uniform管浮點,randint管整數(shù),參數(shù)格式一樣。
正態(tài)分布
正態(tài)分布的本質(zhì):大部分?jǐn)?shù)據(jù)擠在中間,越往兩頭越稀疏。人的身高、考試成績、測量誤差,都近似這個分布。
# 均值0,標(biāo)準(zhǔn)差1,3×3的正態(tài)分布隨機(jī)數(shù)組 np.random.normal(0, 1, (3, 3)) # 簡寫版:標(biāo)準(zhǔn)正態(tài)分布 np.random.randn(3, 3)
種子:給隨機(jī)數(shù)寫劇本
隨機(jī)數(shù)其實是"偽隨機(jī)"——由算法按固定規(guī)則生成。設(shè)種子就是把規(guī)則鎖死,讓每次運(yùn)行結(jié)果一模一樣。
np.random.seed(0) a = np.random.random(3) print(a) # 每次運(yùn)行都輸出相同的值
什么時候用?調(diào)試的時候。你的代碼出了bug,想復(fù)現(xiàn)它,就得保證輸入數(shù)據(jù)不變。種子就是你的"存檔點"。
五、特殊數(shù)組:預(yù)制件
np.eye:單位矩陣
ne = np.eye(3) print(ne) # [[1. 0. 0.] # [0. 1. 0.] # [0. 0. 1.]]
對角線是1,其余是0。線性代數(shù)里的"乘法單位元"——任何矩陣乘以它,等于沒乘。
np.empty:未初始化的數(shù)組
ney = np.empty(3) print(ney) # 值是內(nèi)存里的殘留,不確定
像開盲盒——你不知道里面是什么。但它創(chuàng)建速度極快,因為跳過了初始化步驟。適合你確定后面會逐個賦值的場景。
六、數(shù)組屬性:讀懂你的積木
數(shù)組創(chuàng)建好了,怎么了解它?看屬性:
x = np.random.randint(10, size=(3, 4, 5)) # 3層×4行×5列
| 屬性 | 含義 | 本例值 |
|---|---|---|
ndim | 維度數(shù) | 3 |
shape | 各維度大小 | (3, 4, 5) |
size | 元素總數(shù) | 60 |
dtype | 數(shù)據(jù)類型 | int64 |
itemsize | 單個元素占的字節(jié)數(shù) | 8 |
nbytes | 總字節(jié)數(shù) | 480 |
print('維度:', x.ndim) # 3
print('形狀:', x.shape) # (3, 4, 5)
print('大小:', x.size) # 60
print('類型:', x.dtype) # int64
nbytes = itemsize × size,記住這個關(guān)系就行。
七、切片:精準(zhǔn)取值,小心副作用
切片是NumPy最常用的操作之一,但有個坑:切片返回的是視圖,不是副本。
x = np.array([[3, 5, 2, 4],
[7, 6, 8, 8],
[1, 6, 7, 7]])
x_sub = x[:2, :2] # 前兩行、前兩列
print(x_sub)
# [[3 5]
# [7 6]]
視圖的意思是:你改切片,原數(shù)組也跟著變。
x_sub[0, :] = 9 print(x_sub) # [[9 9] [7 6]] print(x) # 原數(shù)組也被改了! # [[9 9 2 4] # [9 9 8 8] # [1 6 7 7]]
這就像你通過窗戶看房間——你在窗外擺了個花瓶,房間里也多了一個。
想獨立操作?用.copy():
x_sub_copy = x[:2, :2].copy() x_sub_copy[0, :] = 1 print(x) # 原數(shù)組不受影響 print(x_sub_copy) # 副本獨立變化
拍了張照片,照片里的改動不會影響真實的房間。
八、變形:reshape與newaxis
reshape:改變形狀,不改內(nèi)容
grid = np.arange(1, 10) # [1 2 3 4 5 6 7 8 9] grid_reshape = grid.reshape((3, 3)) print(grid_reshape) # [[1 2 3] # [4 5 6] # [7 8 9]]
9個元素可以排成3×3,但排不成4×3——元素總數(shù)必須不變。
np.newaxis:增加一個維度
把一維變二維,本質(zhì)是用None插入一個長度為1的維度:
x = np.array([1, 2, 3, 4, 5]) # 變成一行(1×5) x.reshape(1, 5) # [[1 2 3 4 5]] x[np.newaxis, :] # 效果一樣 # 變成一列(5×1) x.reshape(5, 1) # [[1] [2] [3] [4] [5]] x[:, np.newaxis] # 效果一樣
什么時候用?做矩陣運(yùn)算需要對齊維度的時候。比如一個(5,)的向量要和一個(3,5)的矩陣運(yùn)算,得先把向量變成(1,5)。
九、拼接與分 裂:合體與分身
拼接:多個變一個
x = np.array([1, 2, 3]) y = np.array([3, 2, 1]) z = np.array([99, 99, 99]) # 一維拼接 np.concatenate([x, y, z]) # [ 1 2 3 3 2 1 99 99 99]
二維數(shù)組要指定方向:
grid = np.array([[1, 2, 3],
[4, 5, 6]])
# axis=0:上下疊(行方向)
np.concatenate([grid, grid])
# [[1 2 3]
# [4 5 6]
# [1 2 3]
# [4 5 6]]
# axis=1:左右拼(列方向)
np.concatenate([grid, grid], axis=1)
# [[1 2 3 1 2 3]
# [4 5 6 4 5 6]]
還有兩個快捷函數(shù):
np.vstack([x, y, z, grid]) # 垂直棧,等價于axis=0 np.hstack([grid, grid]) # 水平棧,等價于axis=1
分 裂:一個變多個
x = [0, 1, 2, 3, 4, 5, 6, 7, 8] x1, x2, x3 = np.split(x, [3, 5]) print(x1, x2, x3) # [0 1 2] [3 4] [5 6 7 8]
規(guī)則:np.split(數(shù)組, [斷點列表]),N個斷點切出N+1段。
二維的分 裂:
grid = np.arange(16).reshape(4, 4) # 垂直切:按行分 upper, lower = np.vsplit(grid, [2]) # 水平切:按列分 left, right = np.hsplit(grid, [1])
十、通用函數(shù):向量化的魔法
NumPy的運(yùn)算不需要for循環(huán),直接對整個數(shù)組操作——這就是向量化。
x = np.arange(4)
print('x =', x)
print('x + 5 =', x + 5) # [5 6 7 8]
print('x - 5 =', x - 5) # [-5 -4 -3 -2]
print('x * 2 =', x * 2) # [0 2 4 6]
print('x / 2 =', x / 2) # [0. 0.5 1. 1.5]
print('x // 2 =', x // 2) # [0 0 1 1] 取商
print('x % 2 =', x % 2) # [0 1 0 1] 取余
print('x ** 2 =', x ** 2) # [0 1 4 9] 冪運(yùn)算
print('-x =', -x) # [0 -1 -2 -3]
每種運(yùn)算都有對應(yīng)的函數(shù)版本:np.add、np.subtract、np.multiply、np.divide、np.power……
絕對值
x = np.array([-2, -1, 0, 1, 2]) print(np.abs(x)) # [2 1 0 1 2] print(np.absolute(x)) # 效果一樣
復(fù)數(shù)的模
y = np.array([3 - 4j, 4 - 3j, 2 + 0j, 0 + 1j]) print(abs(y)) # [5. 5. 2. 1.]
復(fù)數(shù)取絕對值返回的是模——實部和虛部平方和再開根號。3-4j的模就是√(9+16)=5。
小時候玩積木,一塊一塊往上壘,最后能搭出城堡、飛船、整個城市。現(xiàn)在玩NumPy,一個數(shù)組一個數(shù)組地創(chuàng)建、變形、拼接,最后能處理海量數(shù)據(jù)、訓(xùn)練模型、解決真實問題。
工具變了,本質(zhì)沒變:從最簡單的單元出發(fā),耐心搭建,直到看見全貌。
寫在最后
回顧一下今天搭的"積木":
- 基礎(chǔ)創(chuàng)建:
np.array從列表一步到位,zeros/ones/arange快速生成模板 - 隨機(jī)數(shù)組:
random、uniform、normal各有用途,seed是調(diào)試的存檔點 - 變形與操作:
reshape改形狀、切片取視圖、拼接分 裂玩組合 - 向量化運(yùn)算:告別
for循環(huán),一行代碼搞定批量計算
數(shù)組創(chuàng)建是 NumPy 的起點,不是終點。上面的速查表可以收藏備用,接下來你可以繼續(xù)探索:
- 索引與切片進(jìn)階 — 花式索引、布爾索引
- 廣播機(jī)制 — 不同形狀的數(shù)組如何對齊運(yùn)算
- 線性代數(shù) — 矩陣乘法、特征值分解
- 實戰(zhàn)項目 — 用 NumPy 做圖像處理、數(shù)據(jù)分析
速查表
| 場景 | 函數(shù) | 一句話說明 |
|---|---|---|
| 從列表創(chuàng)建 | np.array() | 最基礎(chǔ),什么都往里塞 |
| 全零 | np.zeros() | 初始化占位 |
| 全一 | np.ones() | 同上 |
| 等差數(shù)列 | np.arange() | 類似range,但返回數(shù)組 |
| 隨機(jī)浮點 | np.random.random() | [0,1)區(qū)間 |
| 指定范圍隨機(jī) | np.random.uniform() | 自定義區(qū)間 |
| 隨機(jī)整數(shù) | np.random.randint() | 整數(shù)版 |
| 正態(tài)分布 | np.random.normal() | 高斯分布 |
| 固定種子 | np.random.seed() | 讓隨機(jī)不隨機(jī) |
| 單位矩陣 | np.eye() | 對角線1,其余0 |
| 未初始化 | np.empty() | 快,但值不確定 |
| 變形 | reshape | 改形狀不改內(nèi)容 |
| 加維度 | np.newaxis | 一維變二維 |
| 拼接 | concatenate/vstack/hstack | 合體 |
| 分 裂 | split/vsplit/hsplit | 分身 |
大家在實際項目中用過哪些 NumPy 的創(chuàng)建技巧?有沒有踩過什么坑?
以上就是Python使用NumPy創(chuàng)建數(shù)組的完全指南的詳細(xì)內(nèi)容,更多關(guān)于Python NumPy創(chuàng)建數(shù)組的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python configparser模塊封裝及構(gòu)造配置文件
這篇文章主要介紹了Python configparser模塊封裝及構(gòu)造配置文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08
Python多進(jìn)程Process和管道Pipe的使用方式
這篇文章主要介紹了Python多進(jìn)程Process和管道Pipe的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
基于Python實現(xiàn)給喜歡的主播自動發(fā)彈幕
這篇文章主要介紹了python如何實現(xiàn)給喜歡的主播自動發(fā)彈幕的功能,文中的示例代碼對我們學(xué)習(xí)Python有一定的幫助,感興趣的朋友可以了解下2021-12-12
wtfPython—Python中一組有趣微妙的代碼【收藏】
Wtfpython講解了大量的Python編譯器的內(nèi)容。這篇文章主要介紹了wtfPython-Python中一些奇妙的代碼,感興趣的朋友跟隨腳本之家小編一起看看吧2018-08-08
Python Flask框架實現(xiàn)簡單加法工具過程解析
這篇文章主要介紹了Python Flask框架實現(xiàn)簡單加法工具過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06

