1. 程式人生 > >資料分析(三)--numpy進階part2

資料分析(三)--numpy進階part2

Numpy進階part2

1. 花哨的索引

我們知道如何利用簡單的索引值(如 arr[0])、切片(如 arr[:5])和布林掩碼(如 arr[arr > 0])獲得並修改部分陣列。

這裡介紹的花哨的索引和前面那些簡單的索引非常類似,但是傳遞的是索引陣列,而不是單個標量。花哨的索引讓我們能夠快速獲得並修改複雜的陣列值的子資料集。

1.1 探索花哨的索引

花哨的索引在概念上非常簡單,它意味著傳遞一個索引陣列來一次性獲得多個數組元素。
例如以下陣列:

In[1]: import numpy as np
    rand = np.random.RandomState(42
) x = rand.randint(100, size=10) print(x) [51 92 14 71 60 20 82 86 74 74] #假設我們希望獲得三個不同的元素,可以用以下方式實現: In[2]: [x[3], x[7], x[2]] Out[2]: [71, 86, 14] #另外一種方法是通過傳遞索引的單個列表或陣列來獲得同樣的結果: In[3]: ind = [3, 7, 4] x[ind] Out[3]: array([71, 86, 60])

利用花哨的索引,結果的形狀與索引陣列的形狀一致,而不是與被索引陣列的形狀一致:

In[4]: ind = np.array([[3
, 7],[4, 5]]) x[ind] Out[4]: array([[71, 86],[60, 20]]) # 花哨的索引也對多個維度適用。假設我們有以下陣列: In[5]: X = np.arange(12).reshape((3, 4)) X Out[5]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])

和標準的索引方式一樣,第一個索引指的是行,第二個索引指的是列:

In[6]: row = np.array([0, 1, 2])
    col = np.array([2
, 1, 3]) X[row, col] Out[6]: array([ 2, 5, 11])

這裡需要注意,結果的第一個值是 X[0, 2],第二個值是 X[1, 1],第三個值是 X[2, 3]。在花哨的索引中,索引值的配對遵循 2.5 節介紹過的廣播的規則。因此當我們將一個列向量和一個行向量組合在一個索引中時,會得到一個二維的結果:

In[7]: X[row[:, np.newaxis], col]
Out[7]: array([[ 2, 1, 3],
              [ 6, 5, 7],
              [10, 9, 11]])

# 這裡,每一行的值都與每一列的向量配對,正如我們看到的廣播的算術運算:
In[8]: row[:, np.newaxis] * col
Out[8]: array([[0, 0, 0],
              [2, 1, 3],
              [4, 2, 6]])

這裡特別需要記住的是,花哨的索引返回的值反映的是廣播後的索引陣列的形狀,而不是被索引的陣列的形狀。

1.2 組合索引

花哨的索引可以和其他索引方案結合起來形成更強大的索引操作:

In[9]: print(X)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

# 可以將花哨的索引和簡單的索引組合使用:
In[10]: X[2, [2, 0, 1]]
Out[10]: array([10, 8, 9])

# 也可以將花哨的索引和切片組合使用:
In[11]: X[1:, [2, 0, 1]]
Out[11]: array([[ 6, 4, 5],
               [10, 8, 9]])

# 更可以將花哨的索引和掩碼組合使用:

In[12]: mask = np.array([1, 0, 1, 0], dtype=bool)
        X[row[:, np.newaxis], mask]
Out[12]: array([[ 0, 2],
               [ 4, 6],
               [ 8, 10]])

索引選項的組合可以實現非常靈活的獲取和修改陣列元素的操作。

1.3 用花哨的索引修改值

花哨的索引可以被用於獲取部分陣列,它也可以被用於修改部分陣列。例如,假設我們有一個索引陣列,並且希望設定陣列中對應的值:

In[18]: x = np.arange(10)
    i = np.array([2, 1, 8, 4])
    x[i] = 99
    print(x)
[ 0 99 99 3 99 5 6 7 99 9]

# 可以用任何的賦值操作來實現,例如:
In[19]: x[i] -= 10
    print(x)
[ 0 89 89 3 89 5 6 7 89 9]

不過需要注意,操作中重複的索引會導致一些意外發生,如:

In[20]: x = np.zeros(10)
    x[[0, 0]] = [4, 6]
    print(x)
[ 6. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

4 去哪裡了呢?這個操作首先賦值 x[0] = 4,然後賦值 x[0] = 6,因此當然 x[0] 的值為 6。以上還算合理,但是設想以下操作:

In[21]: i = [2, 3, 3, 4, 4, 4]
    x[i] += 1
    x
Out[21]: array([ 6., 0., 1., 1., 1., 0., 0., 0., 0., 0.])

你可能期望 x[3] 的值為 2, x[4] 的值為 3,因為這是這些索引值重複的次數。但是為什麼結果不同於我們的預想呢?從概念的角度理解,這是因為 x[i] += 1 是 x[i] = x[i] + 1 的簡寫。 x[i] + 1 計算後,這個結果被賦值給了 x 相應的索引值。記住這個原理後,我們卻發現數組並沒有發生多次累加,而是發生了賦值,顯然這不是我們希望的結果。

因此,如果你希望累加,該怎麼做呢?你可以藉助通用函式中的 at() 方法(在 NumPy 1.8以後的版本中可以使用)來實現。進行如下操作:

In[22]: x = np.zeros(10)
    np.add.at(x, i, 1)
    print(x)
[ 0. 0. 1. 2. 3. 0. 0. 0. 0. 0.]

at() 函式在這裡對給定的操作、給定的索引(這裡是 i)以及給定的值(這裡是 1)執行的是就地操作。另一個可以實現該功能的類似方法是通用函式中的 reduceat() 函式。

2. 陣列的排序

如果你曾經學習過計算機相關的課程,你可能對插入排序、 選擇排序、 歸併排序、 快速排序、 氣泡排序等這些演算法有所瞭解,但是這些都是為了實現一個類似的任務:對一個列表或陣列進行排序。

2.1 NumPy中的快速排序

儘管 Python 有內建的 sort 和 sorted 函式可以對列表進行排序,但是這裡不會介紹這兩個函式,因為NumPy 的 np.sort 函式實際上效率更高。預設情況下, np.sort 的排序演算法是快速排序,其演算法複雜度為 [N log N ],另外也可以選擇歸併排序和堆排序。

對於大多數應用場景,預設的快速排序已經足夠高效了。如果想在不修改原始輸入陣列的基礎上返回一個排好序的陣列,可以使用 np.sort

In[5]: x = np.array([2, 1, 4, 3, 5])
    np.sort(x)
Out[5]: array([1, 2, 3, 4, 5])

# 如果希望用排好序的陣列替代原始陣列,可以使用陣列的 sort 方法:
In[6]: x.sort()
    print(x)
[1 2 3 4 5]

另外一個相關的函式是 argsort,該函式返回的是原始陣列排好序的索引值:

In[7]: x = np.array([2, 1, 4, 3, 5])
    i = np.argsort(x)
    print(i)
[1 0 3 2 4]

以上結果的第一個元素是陣列中最小元素的索引值,第二個值給出的是次小元素的索引值,以此類推。這些索引值可以被用於(通過花哨的索引)建立有序的陣列:

In[8]: x[i]

Out[8]: array([1, 2, 3, 4, 5])

沿著行或列排序:NumPy 排序演算法的一個有用的功能是通過 axis 引數,沿著多維陣列的行或列進行排序,例如:

In[9]: rand = np.random.RandomState(42)
    X = rand.randint(0, 10, (4, 6))
    print(X)
[[6 3 7 4 6 9]
[2 6 7 4 3 7]
[7 2 5 4 1 7]
[5 1 4 0 9 5]]

In[10]: # 對X的每一列排序
    np.sort(X, axis=0)
Out[10]: array([[2, 1, 4, 0, 1, 5],
               [5, 2, 5, 4, 3, 7],
               [6, 3, 7, 4, 6, 7],
               [7, 6, 7, 4, 9, 9]])
In[11]: # 對X每一行排序
    np.sort(X, axis=1)
Out[11]: array([[3, 4, 6, 6, 7, 9],
               [2, 3, 4, 6, 7, 7],
               [1, 2, 4, 5, 7, 7],
               [0, 1, 4, 5, 5, 9]])

需要記住的是,這種處理方式是將行或列當作獨立的陣列,任何行或列的值之間的關係將會丟失!

2.2 部分排序:分隔

有時候我們不希望對整個陣列進行排序,僅僅希望找到陣列中第 K 小的值, NumPy 的np.partition 函式提供了該功能。 np.partition 函式的輸入是陣列和數字 K,輸出結果是一個新陣列,最左邊是第 K 小的值,往右是任意順序的其他值:

In[12]: x = np.array([7, 2, 3, 1, 6, 5, 4])
    np.partition(x, 3)
Out[12]: array([2, 1, 3, 4, 6, 5, 7])

請注意,結果陣列中前三個值是陣列中最小的三個值,剩下的位置是原始陣列剩下的值。在這兩個分隔區間中,元素都是任意排列的。與排序類似,也可以沿著多維陣列任意的軸進行分隔:

In[13]: np.partition(X, 2, axis=1)
Out[13]: array([[3, 4, 6, 7, 6, 9],
               [2, 3, 4, 7, 6, 7],
               [1, 2, 4, 5, 7, 7],
               [0, 1, 4, 5, 9, 5]])

輸出結果是一個數組,該陣列每一行的前兩個元素是該行最小的兩個值,每行的其他值分佈在剩下的位置。

最後NumPy的結構化陣列就不介紹了,因為工作中用的很少,因為如果有大量的結構化資料要處理,那將使用接下來的另外一個模組:Pandas來處理。

相關推薦

資料分析()--numpypart2

Numpy進階part2 1. 花哨的索引 我們知道如何利用簡單的索引值(如 arr[0])、切片(如 arr[:5])和布林掩碼(如 arr[arr > 0])獲得並修改部分陣列。 這裡介紹的花哨的索引和前面那些簡單的索引非常類似,但是傳遞的是

「機器學習」Python資料分析Numpy

請點選此處輸入圖片描述 進階 廣播法則(rule) 廣播法則能使通用函式有意義地處理不具有相同形狀的輸入。 廣播第一法則是,如果所有的輸入陣列維度不都相同,一個“1”將被重複地新增在維度較小的陣列上直至所有的陣列擁有一樣的維度。 廣播第二法則確定長度為1的陣列沿著特

C#學習筆記第發---特性

lose att 宏函數 入參 編程 發生 大寫 numbers 雙擊 一、異常處理機制 編寫的程序在編譯不報錯之後並不是就不會出錯了,在運行時由於邏輯問題或者別的原因還是可能出現各種異常,異常處理機制就是為了處理這種情況。異常處理中需要用到三個關鍵字,try、catch、

「機器學習」Python資料分析Numpy

請點選此處輸入圖片描述 NumPy的主要物件是同種元素的多維陣列。這是一個所有的元素都是一種型別、通過一個正整數元組索引的元素表格(通常是元素是數字)。在NumPy中維度(dimensions)叫做軸(axes),軸的個數叫做秩(rank)。 例如,在3D空間一個點的座標[1,

python資料分析基礎——numpy和matplotlib

numpy庫是python的一個著名的科學計算庫,本文是一個quickstart。 引入:計算BMI BMI = 體重(kg)/身高(m)^2假如有如下幾組體重和身高資料,讓求每組資料的BMI值: weight = [65.4,59.2,63.6,88.4,68.7] heig

黑客攻防入門()shellcode

1. 概說 實際上,編寫shellcode面昨很多障礙和限制,很多時候必須忍受沒有辦法解決問題的痛苦。 2. 問題 首先,在緩衝區裡使用植入shellcode,程式碼裡只能出現一個NULL(0)字元,因為所有的輸入函式,只要檢測到NULL字元就會返回,因此,NULL只能夠出現

玩轉資料結構入門與——第一章:陣列

內容大綱: 使用Java中的陣列 二次封裝屬於我們自己的陣列 向陣列中新增元素 陣列中查詢元素和修改元素 包含,搜尋,刪除功能 使用泛型 動態陣列 簡單的時間複雜度分析 均攤複雜度和防止複雜度振盪 一、java中的陣列 把資

資料分析numpy模組學習

Python模組中的numpy,這是一個處理陣列的強大模組,而該模組也是其他資料分析模組(如pandas和scipy)的核心。 接下面將從這5個方面來介紹numpy模組的內容: 1)陣列的建立 2)有關陣列的屬性和函式 3)陣列元素的獲取--普通索引、切片、布林索引和花式索引 4

python資料分析numpy

(1)在numpy中呼叫numpy.lookfor('keyword')檢視numpy中的所有關鍵字及函式; (2)numpy中的操作物件是array(矩陣),且array中的資料都為相同型別; (3)用numpy.genfromtxt()函式讀.txt檔案; (4)生成矩陣:用numpy.arange

資料分析numpy常用知識點、難點梳理

一、與random有關的一些函式的區別,首先匯入numpy import numpy as np np.random.randint(low, high=None, size=None, dtype=‘l’) 從low到high的範圍隨機取整數填充多維陣列, size用於

Spring Boot() web

一、表單驗證@Valid 示例:@Min @Valid標識屬性為需要驗證的屬性,BindingResult列印錯誤資訊 Girl實體類: package com.mlj.girl.domain; import javax.persistence.Entity; import jav

Python資料分析numpy的使用

在完成了自己的一個小目標後,想繼續往資料探勘和資料分析的方向前進,接下來會陸陸續續的完成學習筆記,方便日後的回顧。在之前的部落格裡有一篇關於numpy的使用:https://blog.csdn.net/totoro1745/article/details/79243465,這裡是進行相關

pythonnumpy(二)

主要內容:排序,搜尋   python列表排序 a = [1,2,3,4,5] # 排序 a.sort() # 預設升序排序,無返回值,直接修改列表元素順序 a.sort(reverse=True) # 按照升序排序 sorted(a) # 內建函式排序,有返回值,建立新的列

Python資料分析利器——numpy簡單教學

numpy是python下的一個第三方資料庫,提供了高效能矩陣運算能力(別問我多高,我也不知道!反正就是高!!),它是大資料、機器學習、影象處理等熱門方向的基礎,是資料分析的一把利器!!! 注意:不知道為什麼,下面程式碼開頭可能有這樣一段程式碼:<span

【Python】資料分析numpy

numpy使用示例 前言 示例程式碼 參考資料 前言 numpy,全稱numeric python,是一個由多維陣列物件和用於處理陣列的例程集合組成的庫,是python資料分析中最基礎

python資料分析numpy學習筆記

1. 首先是安裝anaconda整合環境安裝 首先進入anaconda官網進行下載安裝,安裝成功後就可以引用資料分析的庫洛。 2. numpy的學習 NumPy系統是Python的一種開源的數值計算擴充套件。這種工具可用來儲存和處理大型矩陣,比Python自身的巢狀列表(nested l

Redis(操作

Redis進階操作 Redis事務處理 Redis本身支援事務處理,但是這種支援的事務處理本身是存在設計缺陷的,而且與傳統的關係型資料庫的事務處理有些不同,首先先來看一下Redis中的事務支援命令: 1.開啟事務:multi 2.取消事務:disca

Python資料處理庫pandas教程

在前面一篇文章中,我們對pandas做了一些入門介紹。本文是它的進階篇。在這篇文章中,我們會講解一些更深入的知識。 前言 本文緊接著前一篇的入門教程,會介紹一些關於pandas的進階知識。建議讀者在閱讀本文之前先看完pandas入門教程。 資料訪問 在入門教程中,

python資料分析numpy初始化(一)

以下都用numpy的標準“import numpy as np” 1.numpy是同構資料多維容器,同構即資料型別相同 2.初始化: 2.1np.arange([start,] end [, step

Python資料分析(8)-numpy運算函式

本節主要介紹numpy中的運算函式,有些需要記住並熟練的使用,主要分為三類:數學運算、算數運算、統計運算。 1. 數學函式 1.1 三角函式 因為這些函式都比較簡單,不需要用例項說明。下面列出了函式的名稱以及功能描述,使用時直接查表就可以。