Python Numpy中返回下标操作函数-节约时间的利器
如果覺得Python慢,那么首先應該想到是不是沒有用對。
Numpy是Python中自帶的一個數(shù)值計算庫,包含了大量數(shù)值計算的常用方法。其底層大量使用C/C++(超過50%的代碼量),矩陣計算調(diào)用LAPACK庫(Fortran),同時在大量代碼優(yōu)化的層面做了工作,使得其內(nèi)置方法速度奇快。
Numpy的設計也頗具人性化, 有許多具有特色又好用的方法可供使用。其中以arg開頭函數(shù)就是專門為返回下標(集)而設計的,總共有5個這樣的函數(shù),它們簡單易用,在許多問題里可以將程序極度簡化,從而提高我們的工作效率。
1. argwhere()
這個函數(shù)與where基本一致,主要用于查找元素所在的位置:
a = np.array([46, 57, 23, 39, 1, 10, 0, 120])# 找出a中大于1的所有元素的下標 np.argwhere(a > 1) Out: array([[0],[1],[2],[3],[5],[7]], dtype=int64) # 找出a中所有小于10的元素的下標 np.argwhere(a < 10) Out: array([[4],[6]], dtype=int64)如果拿到一個需要返回元素下標的任務,我們從C直接考慮的話可能想到的是去遍歷元素,再利用一個臨時變量來計數(shù),在匹配過程中返回這個計數(shù)值。雖然實現(xiàn)起來也很簡單,但速度不是很快。而用這種方法,簡單易懂,同時又超快。
2. argmin(),argmax()
最大,最小值的下標。這種操作應該也是我們非常常用的,而這兩個函數(shù)的用法實際上和np.max(),np.min()的用法是完全一樣的。
a = np.array([46, 57, 23, 39, 1, 10, 0, 120]) np.argmin(a) Out: 6 np.argmax(a) Out: 73. argsort()
這個函數(shù)非常厲害,它首先將輸入的數(shù)組進行升序排列,再將排列后各元素的原下標依次返回。這種操作在一些需要聯(lián)動排序的時候特別管用。比如我們之前講過的在PCA的計算過程中,需要對特征值從大到小排序,同時要對它們對應的特征向量也排序。那么這個時候直接返回特征值排序后的原下標就能極大程序上簡化我們的代碼,同時又能節(jié)約大量的時間。
a = np.array([46, 57, 23, 39, 1, 10, 0, 120])np.argsort(a) Out: array([6, 4, 5, 2, 3, 0, 1, 7], dtype=int64)a[np.argsort(a)] Out: array([ 0, 1, 10, 23, 39, 46, 57, 120])上面最后一步主要是為了用它檢驗函數(shù)的正確性,同時也方便對照分析。
根據(jù)第4行的結(jié)果,我們來看前2個元素。它返回值表示:排序后的數(shù)組中第一個元素應該是原數(shù)組中的第7個元素0,第二個元素應該是原數(shù)組中的第5個元素1。那么看看第7行,完全正確。
當然,還有一個問題是np.sort本身只進行升序排列,那么當我們需要降序時直接將下標進行反序即可:
np.argsort(a)[::-1] Out: array([7, 1, 0, 3, 2, 5, 4, 6], dtype=int64)a[np.argsort(a)[::-1]] Out: array([120, 57, 46, 39, 23, 10, 1, 0])4. argpartition()
這也是一個非常神奇的函數(shù),它主要是對應partition函數(shù)。如果只看文檔說明很有可能理解錯誤。所以我們先簡單說明一下函數(shù)的主要參數(shù)的含義。
np.argpartition(a,k)這里a是 我們的原數(shù)組,k比如好理解的一種方式是:若將a進行排序,那么排序后的數(shù)組中的下標為k個元素應該處在其最終的位置。這句話有一點不太好理解。當然如果我們學過歸并排序(快排的基礎)的話,就可以理解這種分組的思路。
這個算法最終返回的下標里面,下標為k的元素一定處在原數(shù)組升序排列后的最終位置,它前面所有值全部小于等于它,后面所有值全部大于等于它,但其前后所有元素內(nèi)的順序是不關(guān)心的。所以這樣就自然而然地能想到,由于它只考慮該元素的最終位置,那么時間復雜度可以在很大程度上降低。
先看一個簡單的例子:
a = np.array([46, 57, 23, 39, 1, 10, 0, 120])np.argpartition(a,3) Out: array([6, 4, 5, 2, 3, 0, 1, 7], dtype=int64)a[np.argpartition(a,3)] Out: array([ 0, 1, 10, 23, 39, 46, 57, 120])這里可以清楚地看到,排序后的元素中下標為3的元素23的前面已經(jīng)全部小于它,后面已經(jīng)全部大于它,因此這個元素已經(jīng)處在其排序后的最終位置了。
那么利用這個功能,我們主要是可以用它來找出元素中第k小的元素或者是第k大的元素所在的下標。
a[np.argpartition(a,3)[3]] Out: 23 # 第四小的元素剛好是23a[np.argpartition(a,-3)[-3]] Out[]: 46 # 這里是倒數(shù)第3小的元素,也就是第3大的元素,正是46另外,上述方法也可以指定具體的排序方法。比如上面提到的這種思想的基本排序方法是歸并排序,其實也可以指定快速排序等方法。不過在數(shù)據(jù)量級不是特別大的情況下差異并不大。
總結(jié)
以上是生活随笔為你收集整理的Python Numpy中返回下标操作函数-节约时间的利器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PCA计算流程详解与实现(Python详
- 下一篇: 模糊数学笔记:五、模糊聚类