久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    圖解NumPy:常用函數的內在機制(上)

     taotao_2016 2021-01-07

    支持大量多維數組和矩陣運算的 NumPy 軟件庫是許多機器學習開發者和研究者的必備工具,本文將通過直觀易懂的圖示解析常用的 NumPy 功能和函數,幫助你理解 NumPy 操作數組的內在機制。

    圖解NumPy:常用函數的內在機制(上)

    NumPy 是一個基礎軟件庫,很多常用的 Python 數據處理軟件庫都使用了它或受到了它的啟發,包括 pandas、PyTorch、TensorFlow、Keras 等。理解 NumPy 的工作機制能夠幫助你提升在這些軟件庫方面的技能。而且在 GPU 上使用 NumPy 時,無需修改或僅需少量修改代碼。

    NumPy 的核心概念是 n 維數組。n 維數組的美麗之處是大多數運算看起來都一樣,不管數組有多少維。但一維和二維有點特殊。本文分為三部分:

    1. 向量:一維數組

    2. 矩陣:二維數組

    3. 三維及更高維

    本文參考了 Jay Alammar 的文章《A Visual Intro to NumPy》并將其作為起點,然后進行了擴充,并做了一些細微修改。

    NumPy 數組和 Python 列表

    乍一看,NumPy 數組與 Python 列表類似。它們都可作為容器,能夠快速獲取和設置元素,但插入和移除元素會稍慢一些。

    NumPy 數組完勝列表的最簡單例子是算術運算:

    圖解NumPy:常用函數的內在機制(上)

    除此之外,NumPy 數組的優勢和特點還包括:

    更緊湊,尤其是當維度大于一維時;

    當運算可以向量化時,速度比列表更快;

    當在后面附加元素時,速度比列表慢;

    通常是同質的:當元素都是一種類型時速度很快。

    圖解NumPy:常用函數的內在機制(上)

    這里 O(N) 的意思是完成該運算所需的時間和數組的大小成正比,而 O*(1)(即所謂的「均攤 O(1)」)的意思是完成運算的時間通常與數組的大小無關。

    向量:一維數組

    向量初始化

    為了創建 NumPy 數組,一種方法是轉換 Python 列表。NumPy 數組類型可以直接從列表元素類型推導得到。

    圖解NumPy:常用函數的內在機制(上)

    要確保向其輸入的列表是同一種類型,否則你最終會得到 dtype=’object’,這會影響速度,最終只留下 NumPy 中含有的語法糖。

    NumPy 數組不能像 Python 列表一樣增長。數組的末端沒有留下任何便于快速附加元素的空間。因此,常見的做法是要么先使用 Python 列表,準備好之后再將其轉換為 NumPy 數組,要么是使用 np.zeros 或 np.empty 預先留下必要的空間:

    圖解NumPy:常用函數的內在機制(上)

    通常我們有必要創建在形狀和元素類型上與已有數組匹配的空數組。

    圖解NumPy:常用函數的內在機制(上)

    事實上,所有用于創建填充了常量值的數組的函數都帶有 _like 的形式:

    圖解NumPy:常用函數的內在機制(上)

    NumPy 中有兩個函數能用單調序列執行數組初始化:

    圖解NumPy:常用函數的內在機制(上)

    如果你需要類似 [0., 1., 2.] 這樣的浮點數數組,你可以修改 arange 輸出的類型:arange(3).astype(float),但還有一種更好的方法。arange 函數對類型很敏感:如果你以整型數作為參數輸入,它會生成整型數;如果你輸入浮點數(比如 arange(3.)),它會生成浮點數。

    但 arange 并不非常擅長處理浮點數:

    圖解NumPy:常用函數的內在機制(上)

    在我們眼里,這個 0.1 看起來像是一個有限的十進制數,但計算機不這么看。在二進制表示下,0.1 是一個無限分數,因此必須進行約分,也由此必然會產生誤差。也因為這個原因,如果向 arange 函數輸入帶分數部分的 step,通常得不到什么好結果:你可能會遇到差一錯誤 (off-by-one error)。你可以使該區間的末端落在一個非整數的 step 數中(solution1),但這會降低代碼的可讀性和可維護性。這時候,linspace 就可以派上用場了。它不受舍入的影響,總能生成你要求的元素數值。不過,使用 linspace 時會遇到一個常見的陷阱:它統計的是數據點的數量,而不是區間,因此其最后一個參數 num 通常比你所想的數大 1。因此,上面最后一個例子中的數是 11,而不是 10。

    在進行測試時,我們通常需要生成隨機數組:

    圖解NumPy:常用函數的內在機制(上)

    向量索引

    一旦你的數組中有了數據,NumPy 就能以非常巧妙的方式輕松地提供它們:

    圖解NumPy:常用函數的內在機制(上)

    除了「花式索引(fancy indexing)」外,上面給出的所有索引方法都被稱為「view」:它們并不存儲數據,也不會在數據被索引后發生改變時反映原數組的變化情況。

    所有包含花式索引的方法都是可變的:它們允許通過分配來修改原始數組的內容,如上所示。這一功能可通過將數組切分成不同部分來避免總是復制數組的習慣。

    圖解NumPy:常用函數的內在機制(上)

    Python 列表與 NumPy 數組的對比

    為了獲取 NumPy 數組中的數據,另一種超級有用的方法是布爾索引(boolean indexing),它支持使用各類邏輯運算符:

    圖解NumPy:常用函數的內在機制(上)

    any 和 all 的作用與在 Python 中類似,但不會短路。

    不過要注意,這里不支持 Python 的「三元比較」,比如 3<=a<=5。

    如上所示,布爾索引也是可寫的。其兩個常用功能都有各自的專用函數:過度重載的 np.where 函數和 np.clip 函數。它們的含義如下:

    圖解NumPy:常用函數的內在機制(上)

    向量運算

    NumPy 在速度上很出彩的一大應用領域是算術運算。向量運算符會被轉換到 C++ 層面上執行,從而避免緩慢的 Python 循環的成本。NumPy 支持像操作普通的數那樣操作整個數組。

    圖解NumPy:常用函數的內在機制(上)

    與 Python 句法一樣,a//b 表示 a 除 b(除法的商),x**n 表示 x?。

    正如加減浮點數時整型數會被轉換成浮點數一樣,標量也會被轉換成數組,這個過程在 NumPy 中被稱為廣播(broadcast)。

    圖解NumPy:常用函數的內在機制(上)

    大多數數學函數都有用于處理向量的 NumPy 對應函數:

    圖解NumPy:常用函數的內在機制(上)

    標量積有自己的運算符:

    圖解NumPy:常用函數的內在機制(上)

    執行三角函數時也無需循環:

    圖解NumPy:常用函數的內在機制(上)

    我們可以在整體上對數組進行舍入:

    圖解NumPy:常用函數的內在機制(上)

    floor 為舍、ceil 為入,around 則是舍入到最近的整數(其中 .5 會被舍掉)

    NumPy 也能執行基礎的統計運算:

    圖解NumPy:常用函數的內在機制(上)

    NumPy 的排序函數沒有 Python 的排序函數那么強大:

    圖解NumPy:常用函數的內在機制(上)

    Python 列表與 NumPy 數組的排序函數對比

    在一維情況下,如果缺少 reversed 關鍵字,那么只需簡單地對結果再執行反向,最終效果還是一樣。二維的情況則會更困難一些(人們正在請求這一功能)。

    搜索向量中的元素

    與 Python 列表相反,NumPy 數組沒有索引方法。人們很久之前就在請求這個功能,但一直還沒實現。

    圖解NumPy:常用函數的內在機制(上)

    Python 列表與 NumPy 數組的對比,index() 中的方括號表示可以省略 j 或同時省略 i 和 j。

    一種查找元素的方法是 np.where(a==x)[0][0],但這個方法既不優雅,速度也不快,因為它需要檢查數組中的所有元素,即便所要找的目標就在數組起始位置也是如此。

    另一種更快的方式是使用 Numba 來加速 next((i[0] for i, v in np.ndenumerate(a) if v==x), -1)。

    一旦數組的排序完成,搜索就容易多了:v = np.searchsorted(a, x); return v if a[v]==x else -1 的速度很快,時間復雜度為 O(log N),但它需要 O(N log N) 時間先排好序。

    事實上,用 C 來實現它進而加速搜索并不是問題。問題是浮點比較。這對任何數據來說都不是一種簡單直接可用的任務。

    比較浮點數

    函數 np.allclose(a, b) 能在一定公差下比較浮點數數組。

    圖解NumPy:常用函數的內在機制(上)

    函數 np.allclose(a, b) 的工作過程示例。并沒有萬能方法!

    np.allclose 假設所有被比較的數都在典型的 1 的范圍內。舉個例子,如果要在納秒級的速度內完成計算,則需要用默認的 atol 參數值除以 1e9:np.allclose(1e-9, 2e-9, atol=1e-17) == False.

    math.isclose 則不會對要比較的數進行任何假設,而是依賴用戶給出合理的 abs_tol 值(對于典型的 1 的范圍內的值,取默認的 np.allclose atol 值 1e-8 就足夠好了):math.isclose(0.1+0.2–0.3, abs_tol=1e-8)==True.

    除此之外,np.allclose 在絕對值和相對公差的公式方面還有一些小問題,舉個例子,對于給定的 a 和 b,存在 allclose(a, b) != allclose(b, a)。這些問題已在(標量)函數 math.isclose 中得到了解決,我們將在后面介紹它。對于這方面的更多內容,請參閱 GitHub 上的浮點數指南和對應的 NumPy 問題(https:///errors/comparison/)。

    矩陣:二維數組

    NumPy 曾有一個專門的 matrix 類,但現在已經棄用了,所以本文會交替使用「矩陣」和「二維數組」這兩個術語。

    矩陣的初始化句法與向量類似:

    圖解NumPy:常用函數的內在機制(上)

    這里必須使用雙括號,因為第二個位置參數是 dtype(可選,也接受整數)。

    隨機矩陣生成的句法也與向量的類似:

    圖解NumPy:常用函數的內在機制(上)

    二維索引的句法比嵌套列表更方便:

    圖解NumPy:常用函數的內在機制(上)

    view 符號的意思是當切分一個數組時實際上沒有執行復制。當該數組被修改時,這些改變也會反映到切分得到的結果上。

    axis 參數

    在很多運算中(比如 sum),你需要告訴 NumPy 是在列上還是行上執行運算。為了獲取適用于任意維度的通用符號,NumPy 引入了 axis 的概念:事實上,axis 參數的值是相關問題中索引的數量:第一個索引為 axis=0,第二個索引為 axis=1,以此類推。因此在二維情況下,axis=0 是按列計算,axis=1 是按行計算。

    圖解NumPy:常用函數的內在機制(上)

    矩陣算術運算

    除了逐元素執行的常規運算符(比如 +、-、、/、//、*),這里還有一個計算矩陣乘積的 @ 運算符:

    圖解NumPy:常用函數的內在機制(上)

    我們已在第一部分介紹過標量到數組的廣播,在其基礎上進行泛化后,NumPy 支持向量和矩陣的混合運算,甚至兩個向量之間的運算:

    圖解NumPy:常用函數的內在機制(上)

    二維數組中的廣播

    行向量和列向量

    正如上面的例子所示,在二維情況下,行向量和列向量的處理方式有所不同。這與具備某類一維數組的 NumPy 實踐不同(比如二維數組 a— 的第 j 列 a[:,j] 是一個一維數組)。默認情況下,一維數組會被視為二維運算中的行向量,因此當用一個矩陣乘以一個行向量時,你可以使用形狀 (n,) 或 (1, n)——結果是一樣的。如果你需要一個列向量,則有多種方法可以基于一維數組得到它,但出人意料的是「轉置」不是其中之一。

    圖解NumPy:常用函數的內在機制(上)

    基于一維數組得到二維數組的運算有兩種:使用 reshape 調整形狀和使用 newaxis 進行索引:

    圖解NumPy:常用函數的內在機制(上)

    其中 -1 這個參數是告訴 reshape 自動計算其中一個維度大小,方括號中的 None 是用作 np.newaxis 的快捷方式,這會在指定位置添加一個空 axis。

    因此,NumPy 共有三類向量:一維向量、二維行向量和二維列向量。下圖展示了這三種向量之間的轉換方式:

    圖解NumPy:常用函數的內在機制(上)

    一維向量、二維行向量和二維列向量之間的轉換方式。根據廣播的原則,一維數組可被隱含地視為二維行向量,因此通常沒必要在這兩者之間執行轉換——因此相應的區域被陰影化處理。

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 久久午夜无码免费| 国产曰批视频免费观看完| 婷婷色香五月综合缴缴情香蕉| 国产精品国产三级国快看| 日韩夜夜高潮夜夜爽无码| 少妇无套内谢免费视频| 精品国偷自产在线视频99| 国产综合色在线精品| 老王亚洲AV综合在线观看| 人妻 日韩 欧美 综合 制服| 成人啪精品视频网站午夜| 精品久久香蕉国产线看观看亚洲| 99久久婷婷国产综合精品青草漫画 | 亚洲国内精品一区二区| 久久精品A一国产成人免费网站 | 国产精品自在线拍国产电影 | 亚洲AV日韩AV不卡在线观看| 欧美肥老太牲交大战| 久久夜色精品国产嚕嚕亚洲AV | 国产精品日本一区二区在线播放| 日本高清中文字幕免费一区二区| 久久久久99精品国产片| 成年在线观看免费人视频| 最新国产精品久久精品| 成人特黄A级毛片免费视频 | 精品少妇人妻AV无码久久| 第一精品福利导福航| 一区二区三区国产不卡| 人妻少妇久久中文字幕| 国产在线亚州精品内射| 亚洲国产精品午夜福利| 一区二区三区无码免费看| 少妇富婆高级按摩出水高潮| 中文字幕人妻精品在线| 国产免费看插插插视频| 免费人成黄页在线观看国产| 狠狠亚洲色一日本高清色| 丰满少妇被猛烈进出69影院| 影音先锋女人AA鲁色资源| 国产成熟妇女性视频电影| 国产成人亚洲欧美二区综合|