1. 程式人生 > >NumPy之一:基本操作

NumPy之一:基本操作

  NumPy的主要物件是同類多維陣列,這是一個相同型別的元素(通常是數字)組成的表。在NumPy中,維度稱為axis,axis的數量叫做rank

  例如,三維空間中的一個座標為[1, 2, 1]的點,即為rank=1的陣列,因為這個陣列只有一個axis。有些人可能會有疑惑,不是說三維空間麼,為什麼說它只有一個axis呢?axis可以理解成軸,拋開這個點,單看這個陣列[1, 2, 1],它確實只需要一個axis即可表示。這個axis長度為3。

  又如,[[ 1., 0., 0.],[ 0., 1., 2.]],這個陣列的rank=2(2維的)。第一維(axis)長度為2,第二維長度為3。
  
  也可以這麼理解,陣列是由2個行向量組成,所以第一維長度為2,每個行向量由3個向量(點)組成,所以第二維長度為3。

  Numpy的陣列類稱為ndarray。numpy.array和Python標準庫中的array.array是兩回事,標準庫中的array.array只能處理一維陣列且只提供了少數的功能。ndarray物件中更加重要的特性如下:

  • ndarray.ndim
    陣列的axis(維)的數量。在Python中,維的數量被稱作rank。

  • ndarray.shape
    陣列的各個維(注意和維和維數要區分開)。它是一個數組各個維的長度構成的整數元組。對n行m列矩陣而言,shape將是(n,m)。因此,shape元組的長度也就是rank,也是維數ndim。

  • ndarray.size
    陣列所有元素總數量。等於shpe元組各元素的乘積。

  • ndarray.dtype
    一個描述陣列中元素型別的物件。使用者可以使用Python標準型別建立或指定dtype。此外,NumPy還提供了其自有的型別,比如numpy.int32, numpy.int16, numpy.float64。

  • ndarray.itemsize
    陣列各元素的佔多少位元組。比如,一個元素型別是float64的陣列,其itemsize為8(=64/8,64位除以8)。同理,元素型別是complex32的陣列的itemsize為4(=32/8)。ndarray.itemsize等於ndarray.dtype.itemsize。

  • ndarray.data
    裝載陣列真實元素的緩衝區。通常,我們用不到這個屬性,因為我們一般使用索引訪問陣列元素。

1. 一個例子

>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.ndim
2
>>> a.dtype.name
'int64'
>>> a.itemsize
8
>>> a.size
15
>>> type(a)
<type 'numpy.ndarray'>
>>> b = np.array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)
<type 'numpy.ndarray'>

2. 建立陣列

  有多種方法來建立陣列。
  你可以利用常規的Python列表或元組同夥array函式來建立一個數組。創建出的陣列型別和序列元素型別是一致的。

>>> import numpy as np
>>> a = np.array([2,3,4])
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int64')
>>> b = np.array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64')
>>> c = np.array(('a','b','c'))
>>> c
array(['a', 'b', 'c'],
      dtype='|S1')
>>> c.shape
(3,)
>>> c.size
3
>>> c.ndim
1
>>> c.dtype
dtype('S1')

  注意,array函式只接收一個引數,且這個引數是一個python序列。常見的錯誤是給array函式傳遞多個數字作為引數,如a = np.array(1,2,3,4)

  陣列將序列組成的序列轉化為二維陣列,將序列組成的序列組成的序列轉化為三維陣列,如此等等。

>>> b = np.array([(1.5,2,3), (4,5,6)])
>>> b
array([[ 1.5,  2. ,  3. ],
       [ 4. ,  5. ,  6. ]])

  陣列型別也可以在建立的時候明確指定。

>>> c = np.array([[1, 2], [3, 4]], dtype=complex)
>>> c
array([[ 1.+0.j,  2.+0.j],
       [ 3.+0.j,  4.+0.j]])

  一般情況是,陣列元素最初是未知的,但其size是已知的。因此,NumPy提供了一些函式,利用初始的佔位符來建立陣列。這些函式減少了費時費力的手動填充陣列的成本。

  函式zeros可以建立一個全部填充0的陣列;函式ones建立的陣列全部填充為1;函式empty建立的函式的初始內容是隨機的,依賴於記憶體狀態。預設情況下,這些函式建立的陣列的dtype是float64。

>>> a = np.zeros((3,4))
>>> a
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> a.dtype
dtype('float64')
>>> np.ones((2,3,4), dtype = np.int16)
array([[[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]],

       [[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]]], dtype=int16)
>>> np.empty((2,3))
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

  Numpy提供了一個類似於range的函式,可以返回一列數字,用以代替Python序列來建立陣列。

>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])
>>> np.arange( 0, 2, 0.3 )                 # it accepts float arguments
array([ 0. ,  0.3,  0.6,  0.9,  1.2,  1.5,  1.8])

  當給arange函式傳遞的引數是浮點數時,由於浮點數精度的有限性,通常難以預測最終將獲得什麼樣的數字。基於此,一般更好的方法是使用函式linspace,其接收一個我們想要的元素數量作為引數,而不是step:

>>> from numpy import pi
>>> np.linspace( 0, 2, 9 )   # 9 numbers from 0 to 2
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])
>>> x = np.linspace( 0, 2*np.pi, 100 )  # useful to evaluate function at lots of points
>>> f = np.sin(x)

3. 列印陣列

  列印陣列時,NumPy通過類似巢狀列表的方式將陣列展現出來,但會遵循以下層次佈局:

  • 最後的那個axis從左往右依次列印
    比如陣列有4維,那麼從左到右列印的是第4維(第4個axis)

  • 倒數第二個axis從上到下列印

  • 其餘的axis也從上到下列印,每個切片由一個空行分開
      
    基於此,一維陣列將列印成一行;二維陣列將列印成一個矩陣;三維陣列將列印成一個矩陣列表。

>>> a = np.arange(6)                         # 1d array
>>> print(a)
[0 1 2 3 4 5]
>>>
>>> b = np.arange(12).reshape(4,3)           # 2d array
>>> print(b)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
>>>
>>> c = np.arange(24).reshape(2,3,4)         # 3d array
>>> print(c)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]
 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

  如果陣列太大難以列印,NumPy將自動跳過陣列的中間部分,僅打印出周邊少量資料。

>>> print(np.arange(10000))
[   0    1    2 ..., 9997 9998 9999]
>>>
>>> print(np.arange(10000).reshape(100,100))
[[   0    1    2 ...,   97   98   99]
 [ 100  101  102 ...,  197  198  199]
 [ 200  201  202 ...,  297  298  299]
 ...,
 [9700 9701 9702 ..., 9797 9798 9799]
 [9800 9801 9802 ..., 9897 9898 9899]
 [9900 9901 9902 ..., 9997 9998 9999]]

  如果不想省略中間部分,可以通過set_printoptions來強制NumPy列印所有資料。

>>> np.set_printoptions(threshold='nan')

4. 基本運算

  在陣列上的算術運算作用於每個元素。運算結果將填充到一個新建立的陣列中。

>>> a = np.array( [20,30,40,50] )
>>> b = np.arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*np.sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a<35
array([ True, True, False, False], dtype=bool)

  不同於許多矩陣語言,在NumPy中,乘號”*”是兩個陣列中位置相同的元素相乘。矩陣乘法通過dot函式或方法來實現:

>>> A = np.array( [[1,1],
...             [0,1]] )
>>> B = np.array( [[2,0],
...             [3,4]] )
>>> A*B                         # elementwise product
array([[2, 0],
       [0, 4]])
>>> A.dot(B)                    # matrix product
array([[5, 4],
       [3, 4]])
>>> np.dot(A, B)                # another matrix product
array([[5, 4],
       [3, 4]])

  有些運算,諸如+=和*=,會直接修改原陣列,而不是建立一個新的陣列。

>>> a = np.ones((2,3), dtype=int)
>>> b = np.random.random((2,3))
>>> a *= 3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b += a
>>> b
array([[ 3.417022  ,  3.72032449,  3.00011437],
       [ 3.30233257,  3.14675589,  3.09233859]])
>>> a += b                  # b is not automatically converted to integer type
Traceback (most recent call last):
  ...
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'

  當不同型別的陣列之間進行運算時,結果陣列的型別與更通用或更精確的陣列的型別一致(稱作向上轉型)。

>>> a = np.ones(3, dtype=np.int32)
>>> b = np.linspace(0,np.pi,3)
>>> b.dtype.name
'float64'
>>> c = a+b
>>> c
array([ 1.        ,  2.57079633,  4.14159265])
>>> c.dtype.name
'float64'
>>> d = np.exp(c*1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
       -0.54030231-0.84147098j])
>>> d.dtype.name
'complex128'

  許多一元運算,比如計算陣列所有元素的總和,是通過ndarray類的方法來實現的。

>>> a = np.random.random((2,3))
>>> a
array([[ 0.18626021,  0.34556073,  0.39676747],
       [ 0.53881673,  0.41919451,  0.6852195 ]])
>>> a.sum()
2.5718191614547998
>>> a.min()
0.1862602113776709
>>> a.max()
0.6852195003967595

  預設情況下,這些應用於陣列的運算表現的好像陣列是一列數字一樣,並不考慮陣列的形狀。但是,通過指定axis引數,可以將運算應用於指定的axis上:

>>> b = np.arange(12).reshape(3,4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> b.sum(axis=0)                            # sum of each column
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1)                            # min of each row
array([0, 4, 8])
>>>
>>> b.cumsum(axis=1)                         # cumulative sum along each row
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])
>>> b.cumsum(axis = 0)
array([[ 0,  1,  2,  3],
       [ 4,  6,  8, 10],
       [12, 15, 18, 21]])

5. 通用函式

  NumPy提供了常見的數學函式,如sin,cos,exp等。在NumPy中,這些函式稱為“通用函式”(ufunc)。這些函式作用於陣列中每個元素,併產生一個新的結果陣列。

>>> B = np.arange(3)
>>> B
array([0, 1, 2])
>>> np.exp(B)
array([ 1.        ,  2.71828183,  7.3890561 ])
>>> np.sqrt(B)
array([ 0.        ,  1.        ,  1.41421356])
>>> C = np.array([2., -1., 4.])
>>> np.add(B, C)
array([ 2.,  0.,  6.])

6. 索引、切片和迭代

  一維陣列可以像Python中的列表等一樣被索引、切片和迭代。

>>> a = np.arange(10)**3
>>> a
array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000    # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
>>> a
array([-1000,     1, -1000,    27, -1000,   125,   216,   343,   512,   729])
>>> a[ : :-1]                                 # reversed a
array([  729,   512,   343,   216,   125, -1000,    27, -1000,     1, -1000])
>>> for i in a:
...     print(i**(1/3.))
...
nan
1.0
nan
3.0
nan
5.0
6.0
7.0
8.0
9.0

  多維陣列的每個axis都有一個索引。這些索引由一組逗號分隔的數字給出。

>>> def f(x,y):
...     return 10*x+y
...
>>> b = np.fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23],
       [30, 31, 32, 33],
       [40, 41, 42, 43]])
>>> b[2,3]
23
>>> b[0:5, 1]                       # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1]                        # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
>>> b[1:3, : ]                      # each column in the second and third row of b
array([[10, 11, 12, 13],
       [20, 21, 22, 23]])

  如果給出的索引少於axis的數量,那麼缺失的索引被認為是整體切片:

>>> b[-1]                                  # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])

  b[i]的括號中的表示式被解析成一個i後面跟著足夠多的冒號“:”,其足以代表其餘的axis。NumPy中還可以使用點“.”寫成b[i,…]的形式。

  (…)表示足夠的冒號來產生一個完整的索引元組。比如,如果x是一個5維陣列(就是說它有5個axis),那麼

  • x[1,2,…] 等價於 x[1,2,:,:,:]
  • x[…,3] 等價於 x[:,:,:,:,3]
  • x[4,…,5,:] 等價於 x[4,:,:,5,:]
>>> c = np.array( [[[  0,  1,  2],               # a 3D array (two stacked 2D arrays)
...                 [ 10, 12, 13]],
...                [[100,101,102],
...                 [110,112,113]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...]                                   # same as c[1,:,:] or c[1]
array([[100, 101, 102],
       [110, 112, 113]])
>>> c[...,2]                                   # same as c[:,:,2]
array([[  2,  13],
       [102, 113]])

  對多維陣列迭代是就第一個axis而言的:

>>> for row in b:
...     print(row)
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]

  不過,如果想要對陣列中每個元素執行一項操作,可以使用flat屬性,它是一個針對陣列所有元素的迭代器:

>>> for element in b.flat:
...     print(element)
...
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33
40
41
42
43

相關推薦

NumPy之一基本操作

一個例子 建立陣列 列印陣列 基本運算 通用函式   NumPy的主要物件是同類多維陣列,這是一個相同型別的元素(通常是數字)組成的表。在NumPy中,維度稱為axis,axis的數量叫做rank。   例如,三維空間中的一個座標為[1,

堆疊的簡單實現之一基本操作(C語言實現)

堆疊(Stack)是一種操作受限的線性表,堆疊的插入和刪除操作只能在一端進行。堆疊遵循著先進後出或者叫後進先出的原則。在堆疊中,允許插入和刪除的一端叫著棧頂(Top),另外一端叫著棧底(Bottom)

JUnit5學習之一基本操作

### 歡迎訪問我的GitHub [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) 內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等; ###

Python筆記---DAY1基本操作、if語句

分支 刪除 font years cto rec else if direct tab 1、輸出字符串: print(“字符串”) 2、用python打開文檔文件: cmd 命令指示器 cd c:\ 其中cd是chang directory更改目錄,用tab鍵可快速尋找

【AI實戰】快速掌握Tensorflow(一)基本操作

Tensorflow是Google開源的深度學習框架,來自於Google Brain研究專案,在Google第一代分散式機器學習框架DistBelief的基礎上發展起來。Tensorflow於2015年11月在GitHub上開源,在2016年4月補充了分散式版本,最新版本為1.10,2018年

資料分析——numpy庫常用基本操作

本人是一個數據分析的愛好者,由於腦子不夠靈光,所以決定通過寫部落格來記錄自己的學習過程。 百度許久,遍歷教程無數,發現做資料分析主要有一下的工具: 1、SAS:SAS(STATISTICAL ANALYSIS SYSTEM,簡稱SAS)公司開發的統計分析軟體,是一個功能強大的資料庫整合平臺。

numpy.array的基本操作(numpy陣列運算)

為什麼要用numpy Python中提供了list容器,可以當作陣列使用。但列表中的元素可以是任何物件,因此列表中儲存的是物件的指標,這樣一來,為了儲存一個簡單的列表[1,2,3]。就需要三個指標和三個整數物件。對於數值運算來說,這種結構顯然不夠高效。 Pyt

C#程式設計學習(04)基本操作學習總結

一、對話方塊窗體的設計 (1)修改exe圖示:專案-->右鍵-->屬性-->應用程式-->圖示和清單-->圖示,選擇要新增的圖示 (2)修改對話方塊圖示: 點選對話方塊 --> 屬性 --> ICON (3)固定對話方塊大小:點選對話方塊

FEIP與MATLAB基本操作

注:即Feature Extraction and Image Processing,特徵提取與影象處理 1. 預設的直方圖是將RGB三個分量一起考慮,可以單獨的根據三個分量的直方圖,觀察兩部和暗部的分佈,選擇區分明顯的分量轉化成灰度影象,有利於背景和物體分割,有利於後面的邊緣檢測等處理。

numpy 入門】-- 基本操作(1)

注:   在這裡,只是選擇一些常用的方法就行了,比如生成陣列中,array()可以有好幾種方式,但本人只是保留了常用的一些   參考:Numpy 官網教程 1. 生成陣列 >

mysql基本操作

mysql基本操作 mysql服務 備份檔案和恢復資料 常用顯示操作 增刪改查 新增使用者 授權使用者 刪除使用者

回鍋DS-3基本操作與指標體驗

(本系列出自一位在工作後“回鍋資料結構”且堅持寫學習反思的網友。他用郵件發給我,徵得他的同意,我在我的部落格中當“原創”連載發出來。和我的關聯是,他的學習路線中,的確有我提供的方法的影子。) 賀老師,現在在看您的資料結構教程視訊,系統的學習資料結構。 1.知識遷移的能力鍛鍊好,這

Python-OpenCV 處理影象(一)基本操作 cv2

0x00. 圖片讀、寫和顯示操作 安裝好 OpenCV 之後,首先嚐試載入一張最簡單的圖片並顯示出來,程式碼示例: 第一種方式使用cv2.cv的LoadImage、ShowImage和SaveImage函式 import cv2.cv as cv # 讀圖片 image=cv.LoadImage('img

初識Haskell 二基本操作和類型Type

命令行 new alt style 單引號 word vision image win 主要介紹Haskell中的基本操作和類型和類型中的註意點。操作環境Windows 對Discrete Mathematics Using a Computer的第一章Introducti

numpy教程基本輸入輸出和檔案輸入輸出Input and output

基本輸入輸出和檔案輸入輸出檔名和檔案物件本節介紹所舉的例子都是傳遞的檔名,也可以傳遞已經開啟的檔案物件.例如對於load和save函式來說,如果使用檔案物件的話,可以將多個數組儲存到一個npy檔案中:>>> a = np.arange(8) >>

postman介面測試系列基本操作總結

最近專案需要介面測試,所以選擇了不少工具對比,最終決定使用postman進行介面測試,這個工具目前使用比較簡單,但是有點還是比較多的,如下:方便切換不同的環境進行介面測試工作,而不用修改變數或程式碼可以在瀏覽器中直接只用外掛(目前谷歌系統外掛已經不更新了)可以和newman和

Apache Flume學習筆記之一基本概念和流程

一、概述 Apache Flume是一個分散式的、可靠的、可用的系統,用於從許多不同的資料來源高效的收集大容量的日誌資料,聚合並傳輸到一個集中的資料儲存。 Apache Flume並不侷限於日誌資

SpringBoot引數校驗機制之一基本驗證概念

引言 在實際專案開發中,我們會對Controller層接收到的引數進行基本的校驗,本文主要介紹SpringBoot專案中使用註解對輸入引數進行初步規則校驗的方法。本文將從以下幾個方面進行闡述。 Rest請求方式 校驗框架 常用的引數校驗註解 程式碼示例

pytorch基本操作

import torch import numpy as np %matplotlib inline import matplotlib.pyplot as plt pytorch中有兩種變數型別,一個是Tensor,一個是Variable。 Tens

Python-OpenCV 處理影象(一)基本操作

0x00. 圖片讀、寫和顯示操作 安裝好 OpenCV 之後,首先嚐試載入一張最簡單的圖片並顯示出來,程式碼示例: 第一種方式使用cv2.cv的LoadImage、ShowImage和SaveImage函式 import cv2.cv as cv # 讀圖片 image=