網(wǎng)站首頁 編程語言 正文
技術(shù)背景
本文所使用的Numpy版本為:Version: 1.20.3。基于Python和C++開發(fā)的Numpy一般被認為是Python中最好的Matlab替代品,其中最常見的就是各種Numpy矩陣類型的運算。對于矩陣的運算而言,取對軸和元素是至關(guān)重要的,這里我們來看看一些常見的Numpy下標取法和標記。
二維矩陣的取法
這里我們定義一個4*4的矩陣用于取下標,為了方便理解,這個矩陣中所有的元素都是不一樣的:
In [1]: import numpy as np In [2]: x = np.arange(16).reshape((4,4)) In [3]: x Out[3]:? array([[ 0, ?1, ?2, ?3], ? ? ? ?[ 4, ?5, ?6, ?7], ? ? ? ?[ 8, ?9, 10, 11], ? ? ? ?[12, 13, 14, 15]])
取單行和單個元素
比如我們想取第一行的所有元素,那么就是x[0],如果想取第一行的第一列的元素,那么就是x[0][0],而在numpy中為了簡化,可以講x[0][0]寫成x[0,0]的形式:
In [4]: id = 0 In [5]: x[id] Out[5]: array([0, 1, 2, 3]) In [6]: x[id][id] Out[6]: 0 In [7]: x[id,id] Out[7]: 0
下標的list和tuple格式區(qū)分
在上一個章節(jié)中我們提到的取單個元素x[0,0]的方法,其實本質(zhì)上等同于x[(0,0)],也就是一個tuple的格式,但是如果把這里的tuple格式換成list,所表示的含義和得到的結(jié)果是完全不一樣的:
In [8]: id = [1,1] In [9]: x[id] Out[9]:? array([[4, 5, 6, 7], ? ? ? ?[4, 5, 6, 7]]) In [10]: x[id,id] Out[10]: array([5, 5]) In [11]: id = (1,1) In [12]: x[id] Out[12]: 5
這里list格式的id,代表的意思是分別取第二行和第二行的內(nèi)容,再放到一個完整的矩陣中。如果id設(shè)置為[1,2]的話,就是分別取第二行和第三行,而不是取第二行的第二個元素。如果需要取第二行的第二列的元素,那么還是需要用tuple的格式來取下標。有一個比較有意思的點是,如果把剛才的下標重復(fù)輸入兩次,也就是x[[1,2],[1,2]]的話,所表示的含義是分別取x[1][1]和x[2][2],再放到同一個矩陣中,也是一種比較常用的分離式取下標的方法。
冒號的使用
在Numpy的下標中,冒號和后置逗號同時出現(xiàn),表示軸向全取,比如x[0,:]表示取x的第一行的所有數(shù)據(jù),x[:,0]表示取第一列的所有數(shù)據(jù):
In [14]: id = 1 In [15]: x[id,:] Out[15]: array([4, 5, 6, 7]) In [16]: x[:,id] Out[16]: array([ 1, ?5, ?9, 13])
現(xiàn)存的list與numpy.array不相兼容的取法
雖然上文我們提到,如果下標被定義成一個list格式的話,就表示分別取。但是目前Numpy的實現(xiàn)中還有這樣的一個遺留問題,就是使用多維的list格式取下標,會自動將最外層轉(zhuǎn)化成tuple的格式,采用tuple的取法。雖然計算時會給出告警,但是目前來說也需要引起一定的注意。
In [17]: id = [[1],[1]] In [18]: x[id]:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result. ? x[id] Out[18]: array([5]) In [19]: id = np.array([[1],[1]]) In [20]: x[id] Out[20]:? array([[[4, 5, 6, 7]], ? ? ? ?[[4, 5, 6, 7]]])
兩個冒號的組合用法
在Numpy中冒號不與后置逗號同時出現(xiàn)時,表示的含義是從冒號前的元素取值到冒號后的元素,比如x[0:3]所表示的元素是[x[0],x[1],x[2]]。如果是兩個冒號連用中間沒有逗號的話,比如x[0:3:2],表示的是每隔2個元素取一個,最后得到的應(yīng)該是[x[0],x[2]]。還有一種非常常見的操作是取[::-1]這樣的下標,所表示的含義就是對當前軸進行倒序。
In [31]: x[::-1] Out[31]:? array([[12, 13, 14, 15], ? ? ? ?[ 8, ?9, 10, 11], ? ? ? ?[ 4, ?5, ?6, ?7], ? ? ? ?[ 0, ?1, ?2, ?3]]) In [32]: x[::-1,::-1] Out[32]:? array([[15, 14, 13, 12], ? ? ? ?[11, 10, ?9, ?8], ? ? ? ?[ 7, ?6, ?5, ?4], ? ? ? ?[ 3, ?2, ?1, ?0]])
用None作擴維
雖然在Numpy中有broadcast和expand_dim之類的函數(shù)可以對矩陣進行擴維或者是廣播,但是更方便的操作是對需要擴展的維度取一個None的下標,比如要把一個(4,4)大小的矩陣擴展成(1,4,4),那么就對下標取[None,:]或者[None,:,:]即可。而如果需要把(4,4)變成(4,1,4),那就需要把None換個位置為[:,None,:]就可以實現(xiàn):
In [33]: x[None,:] Out[33]:? array([[[ 0, ?1, ?2, ?3], ? ? ? ? [ 4, ?5, ?6, ?7], ? ? ? ? [ 8, ?9, 10, 11], ? ? ? ? [12, 13, 14, 15]]]) In [34]: x[:,None,:] Out[34]:? array([[[ 0, ?1, ?2, ?3]], ? ? ? ?[[ 4, ?5, ?6, ?7]], ? ? ? ?[[ 8, ?9, 10, 11]], ? ? ? ?[[12, 13, 14, 15]]]) In [35]: x[:,:,None] Out[35]:? array([[[ 0], ? ? ? ? [ 1], ? ? ? ? [ 2], ? ? ? ? [ 3]], ? ? ? ?[[ 4], ? ? ? ? [ 5], ? ? ? ? [ 6], ? ? ? ? [ 7]], ? ? ? ?[[ 8], ? ? ? ? [ 9], ? ? ? ? [10], ? ? ? ? [11]], ? ? ? ?[[12], ? ? ? ? [13], ? ? ? ? [14], ? ? ? ? [15]]])
高維矩陣的取法
在高維矩陣中,因為沒有了行和列這樣的概念,因此需要從軸上去理解相關(guān)操作,我們先定義一個簡單的三維張量:
In [49]: y = np.arange(32).reshape((2,4,4)) In [50]: y Out[50]:? array([[[ 0, ?1, ?2, ?3], ? ? ? ? [ 4, ?5, ?6, ?7], ? ? ? ? [ 8, ?9, 10, 11], ? ? ? ? [12, 13, 14, 15]], ? ? ? ?[[16, 17, 18, 19], ? ? ? ? [20, 21, 22, 23], ? ? ? ? [24, 25, 26, 27], ? ? ? ? [28, 29, 30, 31]]])
常規(guī)的操作其實都跟前面章節(jié)中介紹二維張量一致,這里我們考慮一種比較特殊的場景。就是如果同樣用二維矩陣的取法去取,只是第一條軸每個元素取一個id,比如取第0條軸的[0,1]元素和第1條軸的[2,3]元素,那么其實最簡單的方案就是在第一個下標的位置加上一個位置元素,這個位置元素用下標id的第一個軸的長度去定義即可:
In [58]: id = np.array([[0,1],[2,3]]) In [59]: y[np.arange(id.shape[0]),id[:,0],id[:,1]] Out[59]: array([ 1, 27])
總結(jié)概要
這篇文章的主要內(nèi)容是梳理在Numpy中經(jīng)常用到的各種取下標的操作,包括但不限于取指定軸的所有元素、取指定位置的單個元素、取指定位置的多個元素、擴維以及取未顯式給定位置的多個元素等等。比較重要的是在Numpy中tuple的取法和list的取法是代表不一樣的含義,并且由于歷史原因,Numpy中存在一些list取法和numpy.array的取法表示不一致的地方,在本文中進行了總結(jié)。
原文鏈接:https://www.cnblogs.com/dechinphy/p/numpy-id.html
相關(guān)推薦
- 2022-05-19 C++實現(xiàn)簡單信息管理系統(tǒng)_C 語言
- 2022-10-23 Redis的過期鍵刪除策略原理說明_Redis
- 2023-02-09 C++存儲持續(xù)性生命周期原理解析_C 語言
- 2023-01-31 python中的%?是什么意思,起到什么作用呢_python
- 2022-12-06 React運行機制超詳細講解_React
- 2023-10-11 MP、MybatisPlus、聯(lián)表查詢、自定義sql、Constants.WRAPPER、ew (一
- 2022-11-04 ASP.NET?MVC使用jQuery的Load方法加載靜態(tài)頁面及注意事項_實用技巧
- 2022-11-12 C++中的數(shù)組、鏈表與哈希表_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支