python数组切片教程_手把手numpy教程【二】——数组与切片
今天是Numpy專題的第二篇,我們來進入正題,來看看Numpy的運算。
上一篇文章當中曾經提到過,同樣大小的數據,使用Numpy的運算速度會是我們自己寫循環來計算的上百倍甚至更多。并且Numpy的API非常簡單,通常只要簡單幾行代碼就可以完成非常復雜的操作。
計算與廣播
在Python中的數組無論是什么類型,我們是無法直接對其中所有的元素進行計算的。想要做到這一點,必須要通過map這樣的方式操作。而Numpy當中,我們可以很方便地對一整個數組或者是矩陣進行各式的計算。
首先,我們先定義一個Numpy的數組:
arr = np.array([[1,2,3],[2,2,3]])
image-20200516161939969
首先而我們來看一下基本的四則運算:
image-20200516162021455
這張圖中我們可以看出兩點,首先是Numpy當中的數組重載了四則運算符,我們可以直接通過加減乘除進行計算。第二點是Numpy自動替我們做了映射,雖然我們運算操作的對象是數組本身,但是Numpy自動替我們映射到了其中的每一個元素。
如果你不喜歡直接運算,想要使用Numpy的api進行調用,也是一樣可以的。Numpy當中也為加減乘除提供了api。
image-20200516162427254
我們甚至還可以比較兩個數組的大小,得到的結果是一個bool型的數組,代表其中每一個元素的大小關系。
image-20200516162534018
除了列舉的這些之外,Numpy當中還提供了許多其他的api來進行各種計算,幾乎囊括了所有常見的數學計算公式。比如log、exp、pow、開方、三角函數等等計算,基本上api的名稱和math當中的一樣,大家也沒有必要都記住,基本上可以根據英文猜出來,一般來說記住常用的,其他的可以等到使用的時候再查閱。
廣播
理解了Numpy中的基本操作之后,接下來要介紹一個非常重要的概念,叫做廣播。如果這個概念理解不到位,那么后來在使用的過程當中,會遇到很多頭疼的問題,或者是總是看不懂別人的代碼。
廣播的英文叫做broadcasting,這個思想應用的范圍很廣,比如分布式消息中間件等很多領域都有化用。在Numpy計算當中,廣播指的是將一個小的數據應用在大數據的計算上。這個概念其實很形象,我們來看個例子。
比如我們想要對Numpy中的數組每一位的元素都加上3,我們當然可以創造出一個同樣大小的數組來,然后再把它們相加。但是大可不必這么麻煩,我們直接用原數組加上3即可,Numpy內部會發現3和我們的數據大小不一致,然后自動幫我們把3拓充到和我們的數據一樣大小的數組再進行計算:
image-20200516162846508
它其實等價于:
np.full_like(arr, 3) + arr
如果你能理解了上面這個操作,那么同樣的,我們要對所有的元素平方或者是開方也都不在話下了:
image-20200516163141477
廣播并不是只可以用在數組和一個整數之間,還可以用在數組和另外一個規模更小的數組當中,但是會對兩者的shape有所要求。Numpy規定,兩個數組的shape必須相等或者其中一個為1才可以執行廣播操作。
比如說剛才我們創建的arry數組的shape是(3, 2),我們可以讓它和一個大小是(1, 2)或者是(3, 1)的“小數組”進行運算,這同樣是支持的。
如果你看不明白上面的計算過程, 我下面用一張圖做一下演示。
從圖中可以看到左邊的數組shape是(2, 3),右邊的數組shape是(2, 1),滿足Numpy對于廣播機制的要求。Numpy會自動對右邊數組shape為1的維度進行廣播,也就是將它復制若干份使得它們的shape相等。如果你把左邊的數組看成是若干個聽廣播的人,右側的數組看成是消息的話,那么廣播機制就是把消息復制若干份,讓每一個聽廣播的人聽到同樣的內容。所以這個名字還是很形象的。
切片
Python中數組為人稱道的很重要的一點就是它的切片操作非常方便,Numpy作為依托于Python的計算包,自然也繼承了這一點,所以在Numpy當中,我們也可以很方便地使用切片功能。切片的使用方法和Python基本是一樣的。
我們用上下標加上冒號來表示我們想要切片的范圍, 和Python一樣,這是一個左閉右開的區間。
我們也可以省略其中的一個范圍,只提供上界或者是下界:
image-20200516165031942
我們還可以上下界都省略,表示全部都要,以及倒序切片的方法也和Python是一樣的。
image-20200516165127699
但是有一點不太一樣,Numpy中的切片和golang中的切片比較像,它代表原數組一段區間的引用,而不是拷貝。也就是說我們修改切片中的內容是會影響原數組的,我們對一個切片賦值,明顯可以發現原數組的對應位置發生了改變。
image-20200516165245162
這么設計的原因和golang是一樣的,因為Numpy是為了大數據計算而誕生的,大數據計算顯然性能是一個非常重要的考量指標。如果這里不是設計成引用,而是拷貝的話,那么當一個大的切片產生的時候,必然會涉及到大量拷貝的操作。不僅非常消耗內存,并且也會占用大量計算資源。如果使用引用可以非常快速地返回結果。
golang當中如此設計,也是一樣的道理。
那問題來了,如果我們想要拷貝出一份切片出來,而不是獲得一個切片應該怎么辦?答案也很簡單,我們可以調用copy方法,獲取一份拷貝。
arr[3:10].copy()
索引
理解了切片的用法之后,我們接下來看看索引。索引也是Numpy當中非常重要的概念,應用也非常普遍。
Numpy當中的索引對應數組中的維度,比如一個二維的數組,當我們用下標訪問的時候,獲得的其實是一個一維的數組。所以如果我們想要訪問一個具體的元素的時候,能做的就是繼續往下指定下標:
image-20200516171154055
這個很好理解,和Python當中的多維數組的用法是一樣的。上面我們用了兩個方括號去鎖定一個元素的位置,為了寫起來方便,我們還可以用逗號分隔查詢。友情提醒,Python原生的數組并不支持這樣的操作,不要搞混哦。
同樣的道理,如果是多維的數組也是一樣的,我們依次寫出從0到k維的坐標來獲取一個固定的元素。如果我們給出的坐標信息較少,那么則會獲得一個數組。
拿3維數組舉例,如果我們訪問的時候只用一個下標,那么我們獲得的是一個二維數組。如果使用兩個下標,則獲得的是一個一維數組。對于更高的維度也是同樣。
結尾
今天的文章我們一起了解了Numpy當中常見的計算api以及廣播和索引機制,關于索引的使用今天只是開了個頭,還有很多非常靈活的用法,由于篇幅的限制,我們分成了多篇文章,會在之后的文章當中一一介紹。
今天介紹的也是Numpy的基礎內容,除了廣播機制稍稍需要思考一下之外,其余的應該都非常簡單,我相信大家都能看明白。Numpy之所以普及,除了速度快之外,api簡單易用,學習成本低也是很大的特點。
關注我,獲取更多精彩文章。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的python数组切片教程_手把手numpy教程【二】——数组与切片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金士顿u盘分区工具_使用U盘工具给电脑硬
- 下一篇: websocket python爬虫_p