numpy.nditer#
- class numpy.nditer(op, flags=None, op_flags=None, op_dtypes=None, order='K', casting='safe', op_axes=None, itershape=None, buffersize=0)[原始碼]#
用於迭代陣列的有效率多維迭代器物件。若要開始使用此物件,請參閱 陣列迭代入門指南。
- 參數:
- opndarray 或 陣列類型的序列
要迭代的陣列。
- flags字串序列,選用
控制迭代器行為的旗標。
buffered
在需要時啟用緩衝。c_index
導致追蹤 C 順序索引。f_index
導致追蹤 Fortran 順序索引。multi_index
導致追蹤多重索引,或每個迭代維度一個索引的元組。common_dtype
導致所有運算元都轉換為通用資料類型,並在必要時複製或緩衝。copy_if_overlap
導致迭代器判斷讀取運算元是否與寫入運算元重疊,並在必要時建立暫時副本以避免重疊。在某些情況下,可能會出現誤判(不必要的複製)。delay_bufalloc
延遲緩衝區的配置,直到呼叫 reset() 為止。允許在將值複製到緩衝區之前,先初始化allocate
運算元。external_loop
導致給定的values
是一維陣列,具有多個值,而不是零維陣列。grow_inner
當同時使用buffered
和external_loop
時,允許value
陣列大小大於緩衝區大小。ranged
允許將迭代器限制為 iterindex 值的子範圍。refs_ok
啟用參考類型(例如物件陣列)的迭代。reduce_ok
啟用廣播的readwrite
運算元的迭代,也稱為縮減運算元。zerosize_ok
允許itersize
為零。
- op_flags字串列表的列表,選用
這是每個運算元的旗標列表。至少必須指定
readonly
、readwrite
或writeonly
其中之一。readonly
指出運算元將僅供讀取。readwrite
指出運算元將供讀取和寫入。writeonly
指出運算元將僅供寫入。no_broadcast
防止廣播運算元。contig
強制運算元資料為連續的。aligned
強制運算元資料對齊。nbo
強制運算元資料採用原生位元組順序。copy
若需要,允許暫時唯讀副本。updateifcopy
若需要,允許暫時讀寫副本。allocate
如果op
參數中為 None,則導致配置陣列。no_subtype
防止allocate
運算元使用子類型。arraymask
指出此運算元是遮罩,用於在寫入具有 'writemasked' 旗標設定的運算元時選取元素。迭代器不會強制執行此操作,但是當從緩衝區寫回陣列時,它只會複製此遮罩指示的元素。writemasked
指出僅當選定的arraymask
運算元為 True 時,才會寫入元素。overlap_assume_elementwise
可用於標記僅以迭代器順序存取的運算元,以便在存在copy_if_overlap
時允許較不保守的複製。
- op_dtypesdtype 或 dtype 的元組,選用
運算元的所需資料類型。如果啟用複製或緩衝,則資料將轉換為/從其原始類型轉換。
- order{‘C’, ‘F’, ‘A’, ‘K’},選用
控制迭代順序。「C」表示 C 順序,「F」表示 Fortran 順序,「A」表示如果所有陣列都是 Fortran 連續的,則為「F」順序,否則為「C」順序,「K」表示盡可能接近陣列元素在記憶體中出現的順序。這也會影響
allocate
運算元的元素記憶體順序,因為它們的配置與迭代順序相容。預設值為「K」。- casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’},選用
控制在建立副本或緩衝時可能發生的資料類型轉換種類。不建議將此設定為「unsafe」,因為它可能會對累積產生不利影響。
「no」表示資料類型完全不應轉換。
「equiv」表示僅允許位元組順序變更。
「safe」表示僅允許可以保留值的轉換。
「same_kind」表示僅允許安全轉換或種類內的轉換,例如 float64 到 float32。
「unsafe」表示可以完成任何資料轉換。
- op_axes整數列表的列表,選用
如果提供,則為每個運算元的整數或 None 列表。運算元的軸列表是從迭代器的維度到運算元維度的映射。可以為條目放置值 -1,導致該維度被視為
newaxis
。- itershape整數元組,選用
迭代器的所需形狀。這允許
allocate
運算元的維度由 op_axes 映射,而不對應於不同運算元的維度,以取得該維度不等於 1 的值。- buffersize整數,選用
當啟用緩衝時,控制暫時緩衝區的大小。設定為 0 表示預設值。
註解
nditer
取代flatiter
。nditer
背後的迭代器實作也由 NumPy C API 公開。Python 公開提供兩個迭代介面,一個遵循 Python 迭代器協定,另一個反映 C 樣式 do-while 模式。在大多數情況下,原生 Python 方法較佳,但如果您需要迭代器的座標或索引,請使用 C 樣式模式。
範例
以下是如何使用 Python 迭代器協定編寫
iter_add
函數的方法>>> import numpy as np
>>> def iter_add_py(x, y, out=None): ... addop = np.add ... it = np.nditer([x, y, out], [], ... [['readonly'], ['readonly'], ['writeonly','allocate']]) ... with it: ... for (a, b, c) in it: ... addop(a, b, out=c) ... return it.operands[2]
以下是相同的函數,但遵循 C 樣式模式
>>> def iter_add(x, y, out=None): ... addop = np.add ... it = np.nditer([x, y, out], [], ... [['readonly'], ['readonly'], ['writeonly','allocate']]) ... with it: ... while not it.finished: ... addop(it[0], it[1], out=it[2]) ... it.iternext() ... return it.operands[2]
以下是外部乘積函數的範例
>>> def outer_it(x, y, out=None): ... mulop = np.multiply ... it = np.nditer([x, y, out], ['external_loop'], ... [['readonly'], ['readonly'], ['writeonly', 'allocate']], ... op_axes=[list(range(x.ndim)) + [-1] * y.ndim, ... [-1] * x.ndim + list(range(y.ndim)), ... None]) ... with it: ... for (a, b, c) in it: ... mulop(a, b, out=c) ... return it.operands[2]
>>> a = np.arange(2)+1 >>> b = np.arange(3)+1 >>> outer_it(a,b) array([[1, 2, 3], [2, 4, 6]])
以下是類似「lambda」ufunc 運作的函數範例
>>> def luf(lamdaexpr, *args, **kwargs): ... '''luf(lambdaexpr, op1, ..., opn, out=None, order='K', casting='safe', buffersize=0)''' ... nargs = len(args) ... op = (kwargs.get('out',None),) + args ... it = np.nditer(op, ['buffered','external_loop'], ... [['writeonly','allocate','no_broadcast']] + ... [['readonly','nbo','aligned']]*nargs, ... order=kwargs.get('order','K'), ... casting=kwargs.get('casting','safe'), ... buffersize=kwargs.get('buffersize',0)) ... while not it.finished: ... it[0] = lamdaexpr(*it[1:]) ... it.iternext() ... return it.operands[0]
>>> a = np.arange(5) >>> b = np.ones(5) >>> luf(lambda i,j:i*i + j/2, a, b) array([ 0.5, 1.5, 4.5, 9.5, 16.5])
如果使用運算元旗標
"writeonly"
或"readwrite"
,則運算元可能是具有 WRITEBACKIFCOPY 旗標的原始資料的檢視。在這種情況下,nditer
必須用作內容管理器,或在使用結果之前必須呼叫nditer.close
方法。當呼叫__exit__
函數時,暫時資料將寫回原始資料,但在此之前不會寫回>>> a = np.arange(6, dtype='i4')[::-2] >>> with np.nditer(a, [], ... [['writeonly', 'updateifcopy']], ... casting='unsafe', ... op_dtypes=[np.dtype('f4')]) as i: ... x = i.operands[0] ... x[:] = [-1, -2, -3] ... # a still unchanged here >>> a, x (array([-1, -2, -3], dtype=int32), array([-1., -2., -3.], dtype=float32))
務必注意,一旦迭代器結束,懸空參考(例如範例中的 x)可能會或可能不會與原始資料 a 共用資料。如果寫回語意處於活動狀態,即如果 x.base.flags.writebackifcopy 為 True,則結束迭代器將會切斷 x 和 a 之間的連線,寫入 x 將不再寫入 a。如果寫回語意未處於活動狀態,則 x.data 仍將指向 a.data 的某部分,並且寫入其中一個將會影響另一個。
內容管理和
close
方法出現在 1.15.0 版中。- 屬性:
- dtypesdtype 的元組
在
value
中提供的值的資料類型。如果啟用緩衝,則這可能與運算元資料類型不同。僅在迭代器關閉之前有效。- finishedbool
是否已完成對運算元的迭代。
- has_delayed_bufallocbool
如果為 True,則迭代器是使用
delay_bufalloc
旗標建立的,並且尚未對其呼叫 reset() 函數。- has_indexbool
如果為 True,則迭代器是使用
c_index
或f_index
旗標建立的,並且屬性index
可用於擷取它。- has_multi_indexbool
如果為 True,則迭代器是使用
multi_index
旗標建立的,並且屬性multi_index
可用於擷取它。- index
當使用
c_index
或f_index
旗標時,此屬性提供對索引的存取權。如果存取且has_index
為 False,則會引發 ValueError。- iterationneedsapibool
迭代是否需要存取 Python API,例如,如果其中一個運算元是物件陣列。
- iterindexint
符合迭代順序的索引。
- itersizeint
迭代器的大小。
- itviews
記憶體中
operands
的結構化檢視,符合重新排序和最佳化的迭代器存取模式。僅在迭代器關閉之前有效。- multi_index
當使用
multi_index
旗標時,此屬性提供對索引的存取權。如果存取且has_multi_index
為 False,則會引發 ValueError。- ndimint
迭代器的維度。
- nopint
迭代器運算元的數量。
operands
運算元的元組operands[Slice]
- shape整數元組
形狀元組,迭代器的形狀。
- value
目前迭代中
operands
的值。通常,這是陣列純量的元組,但如果使用旗標external_loop
,則它是 一維陣列的元組。
方法