N 維陣列 (ndarray)#

ndarray 是一個(通常為固定大小的)多維容器,用於存放相同型別和大小的項目。陣列的維度數量和項目數量由其 shape 定義,shape 是一個 N 個非負整數的 tuple,用於指定每個維度的大小。陣列中項目的型別由一個獨立的 資料型別物件 (dtype) 指定,每個 ndarray 都與其中一個資料型別物件相關聯。

與 Python 中的其他容器物件一樣,ndarray 的內容可以透過 索引或切片 陣列(例如,使用 N 個整數),以及透過 ndarray 的方法和屬性來存取和修改。

不同的 ndarrays 可以共享相同的資料,因此在一個 ndarray 中進行的更改可能在另一個 ndarray 中可見。也就是說,ndarray 可以是另一個 ndarray 的「視圖」,而它所引用的資料由「base」 ndarray 負責管理。ndarrays 也可以是 Python 字串 或實作 memoryviewarray 介面的物件所擁有的記憶體的視圖。

範例

一個 2 維陣列,大小為 2 x 3,由 4 位元組整數元素組成

>>> import numpy as np
>>> x = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
>>> type(x)
<class 'numpy.ndarray'>
>>> x.shape
(2, 3)
>>> x.dtype
dtype('int32')

可以使用類似 Python 容器的語法來索引陣列

>>> # The element of x in the *second* row, *third* column, namely, 6.
>>> x[1, 2]
   6

例如,切片 可以產生陣列的視圖

>>> y = x[:,1]
>>> y
array([2, 5], dtype=int32)
>>> y[0] = 9 # this also changes the corresponding element in x
>>> y
array([9, 5], dtype=int32)
>>> x
array([[1, 9, 3],
       [4, 5, 6]], dtype=int32)

建構陣列#

可以使用 陣列建立常式 中詳述的常式來建構新陣列,也可以使用底層的 ndarray 建構函式

ndarray(shape[, dtype, buffer, offset, ...])

陣列物件表示一個多維、同質的固定大小項目陣列。

索引陣列#

陣列可以使用擴充的 Python 切片語法 array[selection] 來索引。類似的語法也用於存取 結構化資料型別 中的欄位。

另請參閱

陣列索引.

ndarray 的內部記憶體佈局#

ndarray 類別的實例由一段連續的一維電腦記憶體(由陣列擁有,或由其他物件擁有)組成,並結合一個索引方案,將 N 個整數映射到區塊中項目的位置。索引可以變化的範圍由陣列的 shape 指定。每個項目佔用多少位元組以及如何解釋這些位元組由與陣列關聯的 資料型別物件 定義。

記憶體段本質上是一維的,並且有很多不同的方案用於在一個一維區塊中排列 N 維陣列的項目。NumPy 非常靈活,並且 ndarray 物件可以容納任何跨步索引方案。在跨步方案中,N 維索引 \((n_0, n_1, ..., n_{N-1})\) 對應於偏移量(以位元組為單位)

\[n_{\mathrm{offset}} = \sum_{k=0}^{N-1} s_k n_k\]

從與陣列關聯的記憶體區塊的開頭算起。這裡,\(s_k\) 是整數,它們指定陣列的 strides行優先 順序(例如,在 Fortran 語言和 Matlab 中使用)和 列優先 順序(在 C 中使用)方案只是跨步方案的特定類型,並且對應於可以透過跨步定址的記憶體

\[s_k^{\mathrm{column}} = \mathrm{itemsize} \prod_{j=0}^{k-1} d_j , \quad s_k^{\mathrm{row}} = \mathrm{itemsize} \prod_{j=k+1}^{N-1} d_j .\]

其中 \(d_j\) = self.shape[j]

C 和 Fortran 順序都是 連續的,單段記憶體佈局,其中記憶體區塊的每個部分都可以透過索引的某些組合來存取。

注意

連續陣列單段陣列是同義詞,並且在整個文件中可以互換使用。

雖然具有相應標誌設定的 C 樣式和 Fortran 樣式連續陣列可以使用上述跨步來定址,但實際的跨步可能不同。在兩種情況下可能會發生這種情況

  1. 如果 self.shape[k] == 1 則對於任何合法索引 index[k] == 0。這表示在偏移量公式中 \(n_k = 0\),因此 \(s_k n_k = 0\),並且 \(s_k\) = self.strides[k] 的值是任意的。

  2. 如果陣列沒有元素 (self.size == 0),則沒有合法索引,並且永遠不會使用跨步。任何沒有元素的陣列都可以被視為 C 樣式和 Fortran 樣式連續的。

第 1 點表示 selfself.squeeze() 始終具有相同的連續性和 aligned 標誌值。這也表示即使是高維陣列也可以同時是 C 樣式和 Fortran 樣式連續的。

如果所有元素的記憶體偏移量和基本偏移量本身都是 self.itemsize 的倍數,則陣列被認為是對齊的。了解記憶體對齊可以提高大多數硬體上的效能。

警告

對於 C 樣式連續陣列,self.strides[-1] == self.itemsize 或對於 Fortran 樣式連續陣列,self.strides[0] == self.itemsize 通常成立。

除非另有指定,否則新 ndarrays 中的資料採用 列優先 (C) 順序,但是,例如,基本陣列切片 通常會產生不同方案中的 視圖

注意

NumPy 中的幾種演算法適用於任意跨步陣列。但是,某些演算法需要單段陣列。當不規則跨步陣列傳遞到此類演算法時,會自動建立副本。

陣列屬性#

陣列屬性反映了陣列本身固有的資訊。通常,透過其屬性存取陣列可讓您取得,有時還可以設定陣列的內在屬性,而無需建立新陣列。公開的屬性是陣列的核心部分,只有其中一些屬性可以在不建立新陣列的情況下有意義地重設。以下提供了有關每個屬性的資訊。

記憶體佈局#

以下屬性包含有關陣列記憶體佈局的資訊

ndarray.flags

有關陣列記憶體佈局的資訊。

ndarray.shape

陣列維度的元組。

ndarray.strides

遍歷陣列時,在每個維度中步進的位元組元組。

ndarray.ndim

陣列維度的數量。

ndarray.data

指向陣列資料開頭的 Python 緩衝區物件。

ndarray.size

陣列中元素的數量。

ndarray.itemsize

一個陣列元素在位元組中的長度。

ndarray.nbytes

陣列元素消耗的總位元組數。

ndarray.base

如果記憶體來自其他物件,則為基本物件。

資料型別#

另請參閱

資料型別物件

與陣列關聯的資料型別物件可以在 dtype 屬性中找到

ndarray.dtype

陣列元素的資料型別。

其他屬性#

ndarray.T

轉置陣列的視圖。

ndarray.real

陣列的實部。

ndarray.imag

陣列的虛部。

ndarray.flat

陣列上的 1 維迭代器。

陣列介面#

另請參閱

陣列介面協定.

__array_interface__

陣列介面的 Python 端

__array_struct__

陣列介面的 C 端

ctypes 外部函式介面#

ndarray.ctypes

一個簡化陣列與 ctypes 模組互動的物件。

陣列方法#

ndarray 物件有許多方法,它們以某種方式對陣列進行操作或與陣列一起操作,通常傳回陣列結果。以下簡要說明這些方法。(每個方法的文件字串都有更完整的描述。)

對於以下方法,在 numpy 中也有對應的函式:allanyargmaxargminargpartitionargsortchooseclipcompresscopycumprodcumsumdiagonalimagmaxmeanminnonzeropartitionprodputravelrealrepeatreshaperoundsearchsortedsortsqueezestdsumswapaxestaketracetransposevar

陣列轉換#

ndarray.item(*args)

將陣列的元素複製到標準 Python 純量並傳回。

ndarray.tolist()

將陣列作為 a.ndim 層級深的巢狀 Python 純量列表傳回。

ndarray.tostring([order])

tobytes 的相容性別名,行為完全相同。

ndarray.tobytes([order])

建構包含陣列中原始資料位元組的 Python 位元組。

ndarray.tofile(fid[, sep, format])

將陣列作為文字或二進位檔(預設)寫入檔案。

ndarray.dump(file)

將陣列的 pickle 傾印到指定檔案。

ndarray.dumps()

將陣列的 pickle 作為字串傳回。

ndarray.astype(dtype[, order, casting, ...])

陣列的副本,轉換為指定的型別。

ndarray.byteswap([inplace])

交換陣列元素的位元組

ndarray.copy([order])

傳回陣列的副本。

ndarray.view([dtype][, type])

具有相同資料的陣列的新視圖。

ndarray.getfield(dtype[, offset])

將給定陣列的欄位作為特定型別傳回。

ndarray.setflags([write, align, uic])

分別設定陣列標誌 WRITEABLE、ALIGNED、WRITEBACKIFCOPY。

ndarray.fill(value)

用純量值填滿陣列。

形狀操作#

對於 reshape、resize 和 transpose,單個元組引數可以替換為 n 個整數,這些整數將被解釋為 n 元組。

ndarray.reshape(shape, /, *[, order, copy])

傳回一個包含相同資料但具有新形狀的陣列。

ndarray.resize(new_shape[, refcheck])

就地更改陣列的形狀和大小。

ndarray.transpose(*axes)

傳回軸轉置陣列的視圖。

ndarray.swapaxes(axis1, axis2)

傳回一個視圖,其中 axis1axis2 互換。

ndarray.flatten([order])

傳回折疊成一維的陣列副本。

ndarray.ravel([order])

傳回扁平化陣列。

ndarray.squeeze([axis])

a 中移除長度為一的軸。

項目選擇和操作#

對於採用 axis 關鍵字引數的陣列方法,預設為 None。如果 axis 為 None,則將陣列視為一維陣列。axis 的任何其他值都表示操作應沿其進行的維度。

ndarray.take(indices[, axis, out, mode])

傳回從給定索引處的 a 元素形成的陣列。

ndarray.put(indices, values[, mode])

對於索引中的所有 n,設定 a.flat[n] = values[n]

ndarray.repeat(repeats[, axis])

重複陣列的元素。

ndarray.choose(choices[, out, mode])

使用索引陣列從一組選項建構新陣列。

ndarray.sort([axis, kind, order])

就地排序陣列。

ndarray.argsort([axis, kind, order])

傳回將對此陣列進行排序的索引。

ndarray.partition(kth[, axis, kind, order])

以某種方式部分排序陣列中的元素,使第 k 個位置的元素值位於排序陣列中應處的位置。

ndarray.argpartition(kth[, axis, kind, order])

傳回將對此陣列進行分割的索引。

ndarray.searchsorted(v[, side, sorter])

尋找應將 v 的元素插入 a 以保持順序的索引。

ndarray.nonzero()

傳回非零元素的索引。

ndarray.compress(condition[, axis, out])

沿給定軸傳回此陣列的選定切片。

ndarray.diagonal([offset, axis1, axis2])

傳回指定的對角線。

運算方式#

這些方法中有許多採用名為 axis 的引數。在這種情況下,

  • 如果 axisNone (預設值),則陣列會被視為一維陣列,且運算會針對整個陣列執行。如果 self 是 0 維陣列或陣列純量,此行為也是預設行為。(陣列純量是 float32、float64 等類型/類別的實例,而 0 維陣列是精確包含一個陣列純量的 ndarray 實例。)

  • 如果 axis 是整數,則運算會針對給定的軸執行 (針對每個可沿給定軸建立的一維子陣列)。

axis 引數的範例

一個大小為 3 x 3 x 3 的 3 維陣列,對其三個軸中的每一個軸進行加總

>>> import numpy as np
>>> x = np.arange(27).reshape((3,3,3))
>>> x
array([[[ 0,  1,  2],
      [ 3,  4,  5],
      [ 6,  7,  8]],
      [[ 9, 10, 11],
      [12, 13, 14],
      [15, 16, 17]],
      [[18, 19, 20],
      [21, 22, 23],
      [24, 25, 26]]])
>>> x.sum(axis=0)
array([[27, 30, 33],
      [36, 39, 42],
      [45, 48, 51]])
>>> # for sum, axis is the first keyword, so we may omit it,
>>> # specifying only its value
>>> x.sum(0), x.sum(1), x.sum(2)
(array([[27, 30, 33],
      [36, 39, 42],
      [45, 48, 51]]),
array([[ 9, 12, 15],
      [36, 39, 42],
      [63, 66, 69]]),
array([[ 3, 12, 21],
      [30, 39, 48],
      [57, 66, 75]]))

參數 dtype 指定縮減運算 (如加總) 應發生的資料類型。預設的縮減資料類型與 self 的資料類型相同。為了避免溢位,使用較大的資料類型執行縮減可能很有用。

對於多種方法,也可以提供選用的 out 引數,結果將放置在給定的輸出陣列中。out 引數必須是 ndarray 且具有相同數量的元素。它可以具有不同的資料類型,在這種情況下將執行類型轉換。

ndarray.max([axis, out, keepdims, initial, ...])

傳回沿著給定軸的最大值。

ndarray.argmax([axis, out, keepdims])

傳回沿著給定軸的最大值的索引。

ndarray.min([axis, out, keepdims, initial, ...])

傳回沿著給定軸的最小值。

ndarray.argmin([axis, out, keepdims])

傳回沿著給定軸的最小值的索引。

ndarray.clip([min, max, out])

傳回一個陣列,其值被限制在 [min, max] 範圍內。

ndarray.conj()

複數共軛所有元素。

ndarray.round([decimals, out])

傳回將 a 的每個元素四捨五入到給定小數位數的結果。

ndarray.trace([offset, axis1, axis2, dtype, out])

傳回沿著陣列對角線的總和。

ndarray.sum([axis, dtype, out, keepdims, ...])

傳回陣列元素在給定軸上的總和。

ndarray.cumsum([axis, dtype, out])

傳回沿著給定軸的元素的累積總和。

ndarray.mean([axis, dtype, out, keepdims, where])

傳回陣列元素沿著給定軸的平均值。

ndarray.var([axis, dtype, out, ddof, ...])

傳回陣列元素沿著給定軸的變異數。

ndarray.std([axis, dtype, out, ddof, ...])

傳回陣列元素沿著給定軸的標準差。

ndarray.prod([axis, dtype, out, keepdims, ...])

傳回陣列元素在給定軸上的乘積。

ndarray.cumprod([axis, dtype, out])

傳回沿著給定軸的元素的累積乘積。

ndarray.all([axis, out, keepdims, where])

如果所有元素的評估結果都為 True,則傳回 True。

ndarray.any([axis, out, keepdims, where])

如果 a 的任何元素的評估結果為 True,則傳回 True。

算術、矩陣乘法和比較運算#

ndarrays 上的算術和比較運算被定義為逐元素運算,並且通常產生 ndarray 物件作為結果。

每個算術運算 (+-*///%divmod()**pow()<<>>&^|~) 和比較運算 (==<><=>=!=) 都等同於 NumPy 中對應的通用函式 (或簡稱 ufunc)。如需更多資訊,請參閱關於 通用函式 的章節。

比較運算子

ndarray.__lt__(value, /)

傳回 self<value。

ndarray.__le__(value, /)

傳回 self<=value。

ndarray.__gt__(value, /)

傳回 self>value。

ndarray.__ge__(value, /)

傳回 self>=value。

ndarray.__eq__(value, /)

傳回 self==value。

ndarray.__ne__(value, /)

傳回 self!=value。

陣列的真值 (bool())

ndarray.__bool__(/)

如果 self 為 True 則為 True,否則為 False

注意

陣列的真值測試會調用 ndarray.__bool__,如果陣列中的元素數量不是 1,則會引發錯誤,因為此類陣列的真值是模稜兩可的。請改用 .any().all() 來清楚表達在這種情況下的意圖。(如果您希望檢查陣列是否為空,請使用例如 .size > 0。)

一元運算

算術

ndarray.__add__(value, /)

傳回 self+value。

ndarray.__sub__(value, /)

傳回 self-value。

ndarray.__mul__(value, /)

傳回 self*value。

ndarray.__truediv__(value, /)

傳回 self/value。

ndarray.__floordiv__(value, /)

傳回 self//value。

ndarray.__mod__(value, /)

傳回 self%value。

ndarray.__divmod__(value, /)

傳回 divmod(self, value)。

ndarray.__pow__(value[, mod])

傳回 pow(self, value, mod)。

ndarray.__lshift__(value, /)

傳回 self<<value。

ndarray.__rshift__(value, /)

傳回 self>>value。

ndarray.__and__(value, /)

傳回 self&value。

ndarray.__or__(value, /)

傳回 self|value。

ndarray.__xor__(value, /)

傳回 self^value。

注意

  • 任何傳遞給 pow 的第三個引數都會被靜默忽略,因為底層的 ufunc 只接受兩個引數。

  • 由於 ndarray 是一種內建類型 (以 C 語言編寫),因此 __r{op}__ 特殊方法未直接定義。

  • 呼叫以實作陣列的許多算術特殊方法的函式可以使用 __array_ufunc__ 進行修改。

算術,原地運算

ndarray.__iadd__(value, /)

傳回 self+=value。

ndarray.__isub__(value, /)

傳回 self-=value。

ndarray.__imul__(value, /)

傳回 self*=value。

ndarray.__itruediv__(value, /)

傳回 self/=value。

ndarray.__ifloordiv__(value, /)

傳回 self//=value。

ndarray.__imod__(value, /)

傳回 self%=value。

ndarray.__ipow__(value, /)

傳回 self**=value。

ndarray.__ilshift__(value, /)

傳回 self<<=value。

ndarray.__irshift__(value, /)

傳回 self>>=value。

ndarray.__iand__(value, /)

傳回 self&=value。

ndarray.__ior__(value, /)

傳回 self|=value。

ndarray.__ixor__(value, /)

傳回 self^=value。

警告

原地運算將使用由兩個運算元的資料類型決定的精度執行計算,但會靜默地向下轉換結果 (如有必要),使其可以放回陣列中。因此,對於混合精度計算,A {op}= B 可能與 A = A {op} B 不同。例如,假設 a = ones((3,3))。然後,a += 3ja = a + 3j 不同:雖然它們都執行相同的計算,但 a += 3 會轉換結果以使其放回 a 中,而 a = a + 3j 會將名稱 a 重新繫結到結果。

矩陣乘法

ndarray.__matmul__(value, /)

傳回 self@value

注意

矩陣運算子 @@= 是在 Python 3.5 中根據 PEP 465 引入的,而 @ 運算子已在 NumPy 1.10.0 中引入。更多資訊可以在 matmul 文件中找到。

特殊方法#

對於標準函式庫函式

ndarray.__copy__()

如果在陣列上呼叫 copy.copy 時使用。

ndarray.__deepcopy__(memo, /)

如果在陣列上呼叫 copy.deepcopy 時使用。

ndarray.__reduce__()

用於序列化 (pickling)。

ndarray.__setstate__(state, /)

用於反序列化 (unpickling)。

基本自訂

ndarray.__new__(*args, **kwargs)

ndarray.__array__([dtype], *[, copy])

對於 dtype 參數,如果未給定 dtype 或其與陣列的資料類型相符,則傳回對 self 的新引用。

ndarray.__array_wrap__(array[, context], /)

傳回與 self 類型相同的 array 的視圖。

容器自訂:(請參閱 索引)

ndarray.__len__(/)

傳回 len(self)。

ndarray.__getitem__(key, /)

傳回 self[key]。

ndarray.__setitem__(key, value, /)

將 self[key] 設定為 value。

ndarray.__contains__(key, /)

傳回 key in self。

轉換;運算 int()float()complex()。它們僅適用於其中有一個元素的陣列,並傳回適當的純量。

字串表示形式

ndarray.__str__(/)

傳回 str(self)。

ndarray.__repr__(/)

傳回 repr(self)。

用於類型標註的實用方法

ndarray.__class_getitem__(item, /)

傳回 ndarray 類型的參數化包裝器。