NumPy 數(shù)組創(chuàng)建

2021-09-03 18:28 更新

介紹

創(chuàng)建數(shù)組有 6 種通用機制:

  • 從其他 Python 結(jié)構(gòu)(即列表和元組)轉(zhuǎn)換
  • 內(nèi)在的 NumPy 數(shù)組創(chuàng)建函數(shù)(例如 arange、1、0 等)
  • 復制、加入或改變現(xiàn)有數(shù)組
  • 從磁盤讀取數(shù)組,無論是標準格式還是自定義格式
  • 通過使用字符串或緩沖區(qū)從原始字節(jié)創(chuàng)建數(shù)組
  • 使用特殊庫函數(shù)(例如,random)

可以使用這些方法來創(chuàng)建 ndarrays 或Structured arrays。本文檔將介紹創(chuàng)建 ndarray 的一般方法。

1、將 Python 序列轉(zhuǎn)換為 NumPy 數(shù)組

可以使用 Python 序列(例如列表和元組)定義 NumPy 數(shù)組。列表和元組分別使用[...](...)。列表和元組可以定義 ndarray 創(chuàng)建:

  • 一個數(shù)字列表將創(chuàng)建一個一維數(shù)組,
  • 列表的列表將創(chuàng)建一個二維數(shù)組,
  • 進一步的嵌套列表將創(chuàng)建更高維的數(shù)組。通常,任何數(shù)組對象在 NumPy 中都稱為ndarray。

>>> a1D = np.array([1, 2, 3, 4])
>>> a2D = np.array([[1, 2], [3, 4]])
>>> a3D = np.array([[[1, 2], [3, 4]],
                    [[5, 6], [7, 8]]])

使用numpy.array定義新數(shù)組時,應考慮數(shù)組中元素的dtype,可以明確指定。此功能可以更好地控制底層數(shù)據(jù)結(jié)構(gòu)以及如何在 C/C++ 函數(shù)中處理元素。如果你不小心指定了dtype,可能會遇到不必要的溢出,因此:

>>> a = np.array([127, 128, 129], dtype=np.int8)
>>> a
array([ 127, -128, -127], dtype=int8)

一個 8 位有符號整數(shù)表示從 -128 到 127 的整數(shù)。將int8數(shù)組分配給此范圍之外的整數(shù)會導致溢出。此功能經(jīng)常會被誤解。如果使用 mismatching 執(zhí)行計算dtypes,可能會得到不需要的結(jié)果,例如:

>>> a = array([2, 3, 4], dtype = np.uint32)
>>> b = array([5, 6, 7], dtype = np.uint32)
>>> c_unsigned32 = a - b
>>> print('unsigned c:', c_unsigned32, c_unsigned32.dtype)
unsigned c: [4294967293 4294967293 4294967293] uint32
>>> c_signed32 = a - b.astype(np.int32)
>>> print('signed c:', c_signed32, c_signed32.dtype)
signed c: [-3 -3 -3] int64

請注意:當對兩個相同的dtype:?uint32數(shù)組執(zhí)行操作時,結(jié)果數(shù)組的類型相同。當使用不同的dtype執(zhí)行操作時,NumPy 將分配一個新類型,該類型滿足計算中涉及的所有數(shù)組元素,在這里uint32int32都可以表示為int64

默認的 NumPy 行為是分別以 64 位有符號整數(shù)或雙精度浮點數(shù)int64和?來創(chuàng)建數(shù)組float。如果您希望數(shù)組是某種類型,那么您需要指定dtype創(chuàng)建數(shù)組的時間。

2、內(nèi)在的 NumPy 數(shù)組創(chuàng)建函數(shù)

NumPy 有超過 40 個用于創(chuàng)建數(shù)組的內(nèi)置函數(shù),如數(shù)組創(chuàng)建例程中所述。這些函數(shù)可以根據(jù)它們創(chuàng)建的數(shù)組的維度大致分為三類:

  1. 一維數(shù)組
  2. 二維數(shù)組
  3. 數(shù)組

2.1 一維數(shù)組創(chuàng)建函數(shù)

一維數(shù)組創(chuàng)建函數(shù)例如numpy.linspace并且?numpy.arange通常需要至少兩個輸入,start和?stop

numpy.arange創(chuàng)建具有定期遞增值的數(shù)組。查看文檔以獲取完整信息和示例。顯示了一些示例:

>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(2, 10, dtype=float)
array([ 2., 3., 4., 5., 6., 7., 8., 9.])
>>> np.arange(2, 3, 0.1)
array([ 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9])

注意:numpy.arange是使用整數(shù)開始、結(jié)束和步長值。關(guān)于dtype有一些微妙之處。在第二個示例中,dtype被定義了 。在第三個示例中,數(shù)組?dtype=float將容納0.1的步長。由于舍入誤差,stop有時會包含該值。

numpy.linspace將創(chuàng)建具有指定數(shù)量元素的數(shù)組,并在指定的開始值和結(jié)束值之間等距間隔。例如:

>>> np.linspace(1., 4., 6)
array([ 1. ,  1.6,  2.2,  2.8,  3.4,  4. ])

2.2 二維數(shù)組創(chuàng)建函數(shù)

二維數(shù)組創(chuàng)建函數(shù)例如numpy.eyenumpy.diagnumpy.vander?定義表示為二維數(shù)組的特殊矩陣的屬性。

np.eye(n,?m)定義一個二維單位矩陣。i=j(行索引和列索引相等)的元素為 1,其余為 0,如下所示:

>>> np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
>>> np.eye(3, 5)
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.]])

numpy.diag可以定義具有沿對角線給定值的方形二維數(shù)組,或者如果給定二維數(shù)組,則返回僅包含對角元素的一維數(shù)組。這兩個數(shù)組創(chuàng)建函數(shù)在進行線性代數(shù)時會很有幫助,例如:

>>> np.diag([1, 2, 3])
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])
>>> np.diag([1, 2, 3], 1)
array([[0, 1, 0, 0],
       [0, 0, 2, 0],
       [0, 0, 0, 3],
       [0, 0, 0, 0]])
>>> a = np.array([[1, 2], [3, 4]])
>>> np.diag(a)
array([1, 4])

vander(x,?n)將 Vandermonde 矩陣定義為 2D NumPy 數(shù)組。Vandermonde 矩陣的每一列都是輸入一維數(shù)組或列表或元組的遞減冪,?x其中最高多項式階為n-1。此數(shù)組創(chuàng)建例程有助于生成線性最小二乘模型,例如:

>>> np.vander(np.linspace(0, 2, 5), 2)
array([[0.  , 0.  , 1.  ],
       [0.25, 0.5 , 1.  ],
       [1.  , 1.  , 1.  ],
       [2.25, 1.5 , 1.  ],
       [4.  , 2.  , 1.  ]])
>>> np.vander([1, 2, 3, 4], 2)
array([[1, 1],
       [2, 1],
       [3, 1],
       [4, 1]])
>>> np.vander((1, 2, 3, 4), 4)
array([[ 1,  1,  1,  1],
       [ 8,  4,  2,  1],
       [27,  9,  3,  1],
       [64, 16,  4,  1]])

2.3 一般 ndarray 創(chuàng)建函數(shù)

ndarray 創(chuàng)建函數(shù),例如numpy.ones,?numpy.zeros,并random根據(jù)所需的形狀定義數(shù)組。ndarray 創(chuàng)建函數(shù)可以通過指定元組或列表中沿該維度的維度和長度來創(chuàng)建具有任何維度的數(shù)組。

numpy.zeros將創(chuàng)建一個用指定形狀填充 0 值的數(shù)組。默認數(shù)據(jù)類型為float64

>>> np.zeros((2, 3))
array([[0., 0., 0.],
       [0., 0., 0.]])
>>> np.zeros((2, 3, 2))
array([[[0., 0.],
        [0., 0.],
        [0., 0.]],


       [[0., 0.],
        [0., 0.],
        [0., 0.]]])

numpy.ones將創(chuàng)建一個填充有 1 個值的數(shù)組。它zeros在所有其他方面都相同,?例如:

>>> np.ones((2, 3))
array([[ 1., 1., 1.],
       [ 1., 1., 1.]])
>>> np.ones((2, 3, 2))
array([[[1., 1.],
        [1., 1.],
        [1., 1.]],


       [[1., 1.],
        [1., 1.],
        [1., 1.]]])

default_rng結(jié)果的random方法將創(chuàng)建一個數(shù)組,其中填充了 0 到 1 之間的隨機值。它包含在numpy.random?庫中。下面,分別用形狀 (2,3) 和 (2,3,2) 創(chuàng)建了兩個數(shù)組。種子設置為 42,因此你可以重現(xiàn)這些偽隨機數(shù):

>>> import numpy.random.default_rng
>>> default_rng(42).random((2,3))
array([[0.77395605, 0.43887844, 0.85859792],
       [0.69736803, 0.09417735, 0.97562235]])
>>> default_rng(42).random((2,3,2))
array([[[0.77395605, 0.43887844],
        [0.85859792, 0.69736803],
        [0.09417735, 0.97562235]],
       [[0.7611397 , 0.78606431],
        [0.12811363, 0.45038594],
        [0.37079802, 0.92676499]]])

numpy.indices?將創(chuàng)建一組數(shù)組(堆疊為一個更高維度的數(shù)組),每個維度一個,每個代表該維度的變化:

>>> np.indices((3,3))
array([[[0, 0, 0],
        [1, 1, 1],
        [2, 2, 2]],
       [[0, 1, 2],
        [0, 1, 2],
        [0, 1, 2]]])

這對于評估規(guī)則網(wǎng)格上的多維函數(shù)特別有用。

3、復制、加入或改變現(xiàn)有數(shù)組

創(chuàng)建陣列后,可以復制、連接或改變這些現(xiàn)有陣列以創(chuàng)建新陣列。當你將一個數(shù)組或其元素分配給一個新變量時,必須顯式指定numpy.copy該數(shù)組,否則該變量是原始數(shù)組的視圖。考慮以下示例:

>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> b = a[:2]
>>> b += 1
>>> print('a =', a, '; b =', b)
a = [2 3 3 4 5 6]; b = [2 3]

在此示例中,沒有創(chuàng)建新數(shù)組。創(chuàng)建了一個變量,?b用于查看a中的前兩個元素.?當將 1 添加到b時,將通過將 1 添加到a[:2]得到相同的結(jié)果。如果要創(chuàng)建新數(shù)組,請使用numpy.copy數(shù)組創(chuàng)建例程,如下所示:

>>> a = np.array([1, 2, 3, 4])
>>> b = a[:2].copy()
>>> b += 1
>>> print('a = ', a, 'b = ', b)
a =  [1 2 3 4 5 6] b =  [2 3]

有關(guān)更多信息和示例,請查看副本和視圖。 有許多程序加入現(xiàn)有陣列例如numpy.vstack,?numpy.hstacknumpy.block。下面是一個使用 將四個 2×2 數(shù)組連接成一個 4×4 數(shù)組的示例block

>>> A = np.ones((2, 2))
>>> B = np.eye((2, 2))
>>> C = np.zeros((2, 2))
>>> D = np.diag((-3, -4))
>>> np.block([[A, B],
              [C, D]])
array([[ 1.,  1.,  1.,  0. ],
       [ 1.,  1.,  0.,  1. ],
       [ 0.,  0., -3.,  0. ],
       [ 0.,  0.,  0., -4. ]])

其他例程使用類似的語法來連接 ndarrays。檢查例程的文檔以獲取更多示例和語法。

4、 從磁盤讀取數(shù)組,無論是標準格式還是自定義格式

這是創(chuàng)建大型數(shù)組的最常見情況。詳細信息很大程度上取決于磁盤上數(shù)據(jù)的格式。本節(jié)提供有關(guān)如何處理各種格式的一般指示。有關(guān) IO 的更詳細示例,請查看?讀寫文件。

4.1 標準二進制格式

各種字段都有數(shù)組數(shù)據(jù)的標準格式。下面列出了具有已知 Python 庫以讀取它們并返回 NumPy 數(shù)組的那些(可能還有其他一些可以讀取并轉(zhuǎn)換為 NumPy 數(shù)組,因此也請檢查最后一節(jié))

HDF5: h5py
FITS: Astropy

無法直接讀取但不難轉(zhuǎn)換的格式示例是 PIL 等庫支持的格式(能夠讀取和寫入許多圖像格式,例如 jpg、png 等)。

4.2 常見的 ASCII 格式

逗號分隔值 (csv) 和制表符分隔值 (tsv) 文件等分隔文件用于 Excel 和 LabView 等程序。Python 函數(shù)可以逐行讀取和解析這些文件。NumPy 有兩個標準例程用于導入帶有分隔數(shù)據(jù)numpy.loadtxt?和numpy.genfromtxt.?這些函數(shù)在讀寫文件中有更多涉及的用例?。給出一個簡單的例子simple.csv

$ cat simple.csv
x, y
0, 0
1, 1
2, 4
3, 9

導入simple.csv是使用loadtxt以下方法完成的:

>>> np.loadtxt('simple.csv', delimiter = ',', skiprows = 1) 
array([[0., 0.],
       [1., 1.],
       [2., 4.],
       [3., 9.]])

可以使用scipy.io和Pandas讀取更通用的 ASCII 文件。

5、通過使用字符串或緩沖區(qū)從原始字節(jié)創(chuàng)建數(shù)組

可以使用多種方法。如果文件的格式相對簡單,那么可以編寫一個簡單的 I/O 庫,并使用 NumPy?fromfile()函數(shù)和.tofile()方法直接讀取和寫入 NumPy 數(shù)組(但請注意您的字節(jié)順序!)如果存在一個好的 C 或 C++ 庫可以讀取數(shù)據(jù),人們可以用各種技術(shù)包裝該庫,盡管這肯定需要更多的工作,并且需要更高級的知識來與 C 或 C++ 交互。

6、 特殊庫函數(shù)的使用(例如,SciPy、Pandas 和 OpenCV)

NumPy 是 Python 科學計算堆棧中數(shù)組容器的基礎(chǔ)庫。許多 Python 庫,包括 SciPy、Pandas 和 OpenCV,都使用 NumPy ndarrays 作為數(shù)據(jù)交換的通用格式,這些庫可以創(chuàng)建、操作和使用 NumPy 數(shù)組。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號