- 從0到1:Python數據分析
- 莫振杰
- 4143字
- 2022-12-20 18:27:24
2.2 創建數組
NumPy就是用來操作數組的,我們學習NumPy,其實就是學習數組的各種操作。了解了這一點,可以讓后續的學習方向變得更加清晰。
在Python中,可以使用NumPy來創建一個數組。數組和列表很相似,但是它們之間有本質上的區別。
? 列表的元素可以是不同數據類型,而數組的元素必須是同一數據類型。
? 列表不可以進行四則運算,而數組可以進行四則運算。
對于NumPy中的數組,讀者可以簡單地把它看成“增強版的列表”,因為它的功能比列表強大得多。
2.2.1 基本方法
在NumPy中,創建數組的方法有很多,常用的方法如表2-1所示。
表2-1 創建數組的常用方法

除了上表列出的方法,NumPy還有一個empty()方法。empty()在實際開發中用得并不多,這里就不展開介紹了。
1.array()
在NumPy中,可以使用array()來創建一個數組。array()是NumPy中最基礎也是最常用的一個方法。
語法
np.array(列表或元組)
說明
array()的參數可以是一個列表,也可以是一個元組。array()其實就是將一個列表轉換為一個數組,或者將一個元組轉換為一個數組。
舉例:將列表轉換為數組
import numpy as np arr = np.array([1, 2, 3, 4, 5]) print(arr) print(type(arr)) print(arr.dtype)
輸出結果如下:
[1 2 3 4 5] <class 'numpy.ndarray'> int32
分析
從輸出結果可以看出,數組元素之間是用空格隔開的,而不是用逗號隔開的,這一點和列表不一樣。dtype屬性用于獲取數組元素的類型,這個在下一節會詳細介紹。
array()會自動根據“列表元素的類型”來確定“數組元素的數據類型”。np.array()返回的是一個ndarray對象,這個ndarray對象非常重要,我們在后面會大量接觸到。
可能一些讀者會問:為什么要將列表轉換成數組?原因很簡單,對于列表,只能使用列表的方法來對其中的元素進行操作,但是將列表轉換成數組之后,就可以使用數組提供的豐富方法來對其中的元素進行操作了。
舉例:將元組轉換為數組
import numpy as np arr = np.array((1, 2, 3, 4, 5)) print(arr) print(type(arr)) print(arr.dtype)
輸出結果如下:
[1 2 3 4 5] <class "numpy.ndarray"> int32
分析
np.array()除了可以將列表轉換成數組,還可以將元組轉換成數組。不過在實際開發中,我們更多是將一個列表轉換成數組。
2.arange()
在NumPy中,可以使用arange()來創建元素值在“指定范圍”內的一維數組。需要特別注意的是,arange()只能創建一維數組,而不能創建多維數組。
語法
np.arange(start, end, step)
說明
start是開始值,end是結束值,step是步長。np.arange()的取值范圍為[start, end),也就是包含開始值,但是不包含結束值。
? 當np.arange()有一個參數時,表示只有結束值,此時開始值是0。
? 當np.arange()有兩個參數時,表示只有開始值和結束值,此時開始值是start。
? 當np.arange()有3個參數時,表示有開始值、結束值和步長。所謂步長,指的是元素遞增的量。
舉例:一個參數
import numpy as np arr = np.arange(10) print(arr)
輸出結果如下:
[0 1 2 3 4 5 6 7 8 9]
分析
np.arange(10)表示結束值為10,也就是取值范圍為[0, 10)。從結果可以看出,結束值是沒有包含進去的。讀者記住這一點就可以了:不管np.arange()的參數是多少個,結束值都不會被包含進去。
對于這個例子來說,下面3種方式是等價的,讀者可以思考一下為什么:
# 方式1 np.arange(10) # 方式2 np.arange(0, 10) # 方式3 np.arange(0, 10, 1)
舉例:兩個參數
import numpy as np arr = np.arange(5, 10) print(arr)
輸出結果如下:
[5 6 7 8 9]
分析
np.arange(5, 10)表示開始值為5、結束值為10,也就是取值范圍為[5, 10)。對于這個例子來說,下面兩種方式是等價的:
# 方式1 np.arange(5, 10) # 方式2 np.arange(5, 10, 1)
舉例:3個參數
import numpy as np arr = np.arange(10, 30, 3) print(arr)
輸出結果如下:
[10 13 16 19 22 25 28]
分析
np.arange(10, 30, 3)的取值范圍為[10, 30),步長為3。np.arange()不僅可以用于創建元素的類型是整型的數組,還可以用于創建元素的類型是浮點型的數組。
舉例:元素是浮點數
import numpy as np arr = np.arange(1.5, 10.5, 2) print(arr)
輸出結果如下:
[1.5 3.5 5.5 7.5 9.5]
分析
np.arange(1.5, 10.5, 2)的取值范圍為[1.5, 10.5),步長為2。
舉例:步長是浮點數
import numpy as np arr = np.arange(1, 10, 1.5) print(arr)
輸出結果如下:
[1. 2.5 4. 5.5 7. 8.5]
分析
np.arange(1, 10, 1.5)的取值范圍為[1, 10),步長為1.5。np.arange()和range()非常相似,但是它們之間也有一定的區別:range()的步長只能是整數,而np.arange()的步長可以是任意數。
此外,arange()只能創建一維數組。如果想要創建多維數組,可以結合“2.5 數組操作”這一節介紹的reshape()來實現。
3.linspace()
除了arange()之外,還可以使用linspace()來創建元素值在“指定范圍”內的一維數組。
語法
np.linspace(start, end, num, endpoint=True或False)
說明
start是開始值,end是結束值,num是個數。默認情況下,linspace()的取值范圍為[start, end],也就是包含開始值和結束值。但是可以使用endpoint=False,使得它的取值范圍為[start, end)。
舉例:包含結束值
import numpy as np arr = np.linspace(0, 10, 20) print(arr)
輸出結果如下:
[ 0. 0.52631579 1.05263158 1.57894737 2.10526316 2.63157895 3.15789474 3.68421053 4.21052632 4.73684211 5.26315789 5.78947368 6.31578947 6.84210526 7.36842105 7.89473684 8.42105263 8.94736842 9.47368421 10. ]
分析
np.linspace(0, 10, 20)表示開始值為0,結束值為10,元素個數為20。需要注意的是,np.linspace(0, 10, 20)的取值范圍為[0, 10],也就是包含結束值10。如果不希望把結束值包含進去,可以使用endpoint=False。
舉例:不包含結束值
import numpy as np arr = np.linspace(0, 10, 20, endpoint=False) print(arr)
輸出結果如下:
[0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5 7. 7.5 8. 8.5 9. 9.5]
4.zeros()和ones()
在NumPy中,可以使用zeros()來創建一個元素值全為0的數組,也可以使用ones()來創建一個元素值全為1的數組。
語法
np.zeros((a, b, ..., n), dtype=int或float) np.ones((a, b, ..., n), dtype=int或float)
說明
zeros()和ones()都可以接收兩個參數。第1個參數是一個元組,它是一個必選參數,表示創建一個a×b×…×n的數組;第2個參數是一個可選參數,它用于定義元素的類型,默認是float類型。
舉例:默認情況
import numpy as np arr1 = np.zeros((3, 3)) arr2 = np.ones((3, 3)) print(arr1) print(arr2)
輸出結果如下:
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]
分析
實際上,np.zeros((3, 3))是一種簡寫方式,它等價于np.zeros(shape=(3,3))。shape是數組的形狀,下一節會詳細介紹。
對于shape參數來說,它的值是一個元組或列表,所以下面兩種方式是等價的。這兩種方式在實際開發中都會出現,我們需要了解一下:
# 方式1 arr1 = np.zeros((3, 3)) arr2 = np.ones((3, 3)) # 方式2 arr1 = np.zeros([3, 3]) arr2 = np.ones([3, 3])
默認情況下,使用zeros()和ones()創建的數組的元素都是float類型,以下兩種方式是等價的:
# 方式1 arr1 = np.zeros((3, 3)) arr2 = np.ones((3, 3)) # 方式2 arr1 = np.zeros((3, 3), dtype=float) arr2 = np.ones((3, 3), dtype=float)
舉例:int類型
import numpy as np arr1 = np.zeros((3, 3), dtype=int) arr2 = np.ones((3, 3), dtype=int) print(arr1) print(arr2)
輸出結果如下:
[[0 0 0] [0 0 0] [0 0 0]] [[1 1 1] [1 1 1] [1 1 1]]
分析
如果想要將數組元素定義成int類型,可以使用dtype=int。
2.2.2 隨機數組
在實際開發中,有時手動創建的數據并不能滿足開發需求,所以我們還得借助一種特殊數組,那就是“隨機數組”。
在NumPy中,可以使用random模塊來創建一個隨機數組。創建隨機數組的方法主要有3種,如表2-2所示。
表2-2 創建隨機數組的方法

1.randint()
在NumPy中,可以使用random模塊的randint()方法來創建一個整型隨機數組。
語法
np.random.randint(start, end, size=元組或整數)
說明
元素的取值范圍為[start, end),包含start但不包含end。size的取值分為以下兩種情況。
? 當size是一個元組時,size=(m)表示創建一個m行的一維數組,size=(m, n)表示創建一個m×n的二維數組,以此類推。
? 當size是一個整數時,size=m表示創建一個m行的一維數組。實際上,size=(m)和size=m是等價的,因為對于一個數來說,使用“()”和不使用“()”是一樣的。
舉例:一維數組
import numpy as np arr = np.random.randint(10, 20, size=(5)) print(arr)
輸出結果如下:
[14 11 17 16 12]
分析
randint(10, 20, size=(5))表示創建一個包含5個元素的一維隨機數組,元素都是[10, 20)內的整數。
對于這個例子來說,下面3種方式是等價的。這3種方式我們都要了解一下,因為很多地方都會出現:
# 方式1 arr = np.random.randint(10, 20, size=(5)) # 方式2 arr = np.random.randint(10, 20, size=5) # 方式3 arr = np.random.randint(10, 20, 5)
舉例:二維數組
import numpy as np arr = np.random.randint(10, 20, size=(2, 5)) print(arr)
輸出結果如下:
[[14 14 19 12 19] [17 12 15 14 12]]
分析
randint(10, 20, size=(2, 5))表示創建一個2×5的二維隨機數組,元素都是[10, 20)內的整數。2×5也就是2行5列,如圖2-3所示。

圖2-3
對于這個例子來說,以下兩種方式是等價的:
# 方式1 arr = np.random.randint(10, 20, size=(2, 5)) # 方式2 arr = np.random.randint(10, 20, (2, 5))
2.rand()
在NumPy中,可以使用random模塊的rand()方法來創建一個浮點型隨機數組,其元素的取值范圍為[0,1)。
語法
np.random.rand(m, n)
說明
當rand()有一個參數時,例如rand(m),表示創建一個包含m個元素的一維隨機數組。當rand()有兩個參數時,例如rand(m, n),表示創建一個m×n的二維隨機數組。
舉例:一維數組
import numpy as np arr = np.random.rand(5) print(arr)
輸出結果如下:
[0.52039969 0.44537686 0.66946674 0.91937385 0.6516376]
分析
在這個例子中,rand(5)表示創建一個包含5個元素的一維隨機數組。其中,元素都是[1,0)內的浮點數。
舉例:二維數組
import numpy as np arr = np.random.rand(2, 5) print(arr)
輸出結果如下:
[[0.23881446 0.78932247 0.58749747 0.86061954 0.65791401] [0.59769419 0.12579491 0.79234194 0.74421893 0.27629203]]
分析
在這個例子中,rand(2, 5)表示創建一個2×5的二維隨機數組。
3.randn()
在NumPy中,可以使用random模塊的randn()方法來生成一個隨機數組,該數組的元素符合正態分布。
語法
np.random.randn(m, n)
說明
當randn()有一個參數時,例如randn(m),表示創建一個包含m個元素的一維隨機數組。當randn()有兩個參數時,例如randn(m, n),表示創建一個m×n的二維隨機數組。
randn()和rand()的參數是一樣的,只是生成的元素的值不一樣。
舉例:一維數組
import numpy as np arr = np.random.randn(5) print(arr)
輸出結果如下:
[-1.05723124 -0.00507968 -0.20048986 0.0417768 1.51705339]
分析
在這個例子中,randn(5)表示創建一個包含5個元素的一維隨機數組。
舉例:二維數組
import numpy as np arr = np.random.randn(2, 5) print(arr)
輸出結果如下:
[[-2.0953303 0.03843233 -0.63218314 1.22316454 0.21490433] [-0.5237318 -1.01258678 0.58363956 0.11605207 1.39723533]]
分析
在這個例子中,randn(2, 5)表示創建一個2×5的二維隨機數組。需要說明的是,隨機數組在后面的學習中會大量用到,所以randint()、rand()、randn()這幾個方法,讀者要重點掌握。
2.2.3 數組與列表的區別
到這里,讀者可能會有這樣的一個疑問:為什么有了列表之后,還要搞一個數組出來呢?它們之間有什么區別嗎?其實,數組和列表(見圖2-4)最本質的區別在于:它們在內存中的存儲方式不同。

圖2-4
列表可以存儲不同類型的元素,元素可以是數字、字符串、列表、字典等。對于列表中的每一個元素來說,需要為元素分配一定的內存空間來保存元素的類型信息。當所有元素都是同一種類型時,本來只需要存儲一次類型信息就可以了,但是卻要為每一個元素分配“額外的內存”來保存類型信息。此時這些信息是冗余的,并且白白浪費了內存空間。
為了解決這個問題,最好的辦法就是使用只包含相同類型元素的數組。當元素個數非常龐大(例如上百萬)時,列表和數組的性能差異就變得非常明顯了。在對大量數據進行數學操作時,當然也可以使用列表來操作,只是并不推薦這樣去做,因為此時列表的性能太差了。
NumPy中數組的元素要比列表中的元素“純潔”得多,元素的類型只能是同一種數據類型。對于NumPy中的數組來說,元素的類型大多數情況下都是整型或浮點型,很少情況下是其他類型。
舉例:不同類型
import numpy as np arr = np.array([1, "2", True, "4", 5]) print(arr) print(arr.dtype) # 輸出數組的類型
輸出結果如下:
["1" "2" "True" "4" "5"] <U11
分析
np.array()用于將列表轉換為數組,一般要求列表的元素是相同的類型。當列表元素是不同類型時,程序不會報錯,但是并不推薦這樣去做。讀者在使用NumPy數組時,要避免出現這種問題。
【常見問題】
1. 為什么不用[1 2 3 4 5]這樣的方式來創建數組,而是采用np.array()這種更加復雜的方式呢?
這是因為在Python中,中括號已經用于創建列表了。如果數組也使用中括號來創建,那么Python就無法判斷此時創建的到底是列表還是數組了。
2. 為什么NumPy要提供那么多個創建數組的方式呢?
原因其實很簡單,NumPy的核心就是數組。所以不管是創建數組還是操作數組,它都提供了盡可能多的方式,以便我們更好地靈活操作。
3. 對于隨機數組來說,什么情況下包含結束值,什么情況下不包含結束值呢?
對于隨機數組來說,絕大多數情況下都是不包含結束值的。讀者暫且可以先這樣簡單地記憶。
- 黑客攻防從入門到精通(實戰秘笈版)
- OpenCV實例精解
- Linux C/C++服務器開發實踐
- 程序員面試算法寶典
- RTC程序設計:實時音視頻權威指南
- 深入淺出Windows API程序設計:編程基礎篇
- Kotlin Standard Library Cookbook
- 基于Swift語言的iOS App 商業實戰教程
- Mastering JavaScript Design Patterns(Second Edition)
- Bootstrap 4 Cookbook
- HTML+CSS+JavaScript網頁設計從入門到精通 (清華社"視頻大講堂"大系·網絡開發視頻大講堂)
- PHP與MySQL權威指南
- 超簡單:Photoshop+JavaScript+Python智能修圖與圖像自動化處理
- C#面向對象程序設計(第2版)
- Visual C++開發寶典