關於Numpy之repeat、tile的用法總結
repeat函數的作用:①擴充數組元素 ②降低數組維度
numpy.repeat(a, repeats, axis=None):若axis=None,對於多維數組而言,可以將多維數組變化為一維數組,然後再根據repeats參數擴充數組元素;若axis=M,表示數組在軸M上擴充數組元素。
下面以3維數組為例,瞭解下repeat函數的使用方法:
In [1]: import numpy as np In [2]: arr = np.arange(12).reshape(1,4,3) In [3]: arr Out[3]: array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]])
①repeats為整數N,axis=None:數組arr首先被扁平化,然後將數組arr中的各個元素 依次重復N次
In [4]: arr.repeat(2) Out[4]: array([ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11])
②repeats為整數數組rp_arr,axis=None:數組arr首先被扁平化,然後再將數組arr中元素依次重復對應rp_arr數組中元素對應次數。若rp_arr為一個值的一維數組,則數組arr中各個元素重復相同次數,否則rp_arr數組長度必須和數組arr的長度相等,否則報錯
a:rp_arr為單值一維數組,進行廣播
In [5]: arr.repeat([2]) Out[5]: array([ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11])
b:rp_arr長度小於數組arr長度,無法進行廣播,報錯
In [6]: arr.repeat([2,3,4])
—————————————————————————
ValueError Traceback (most recent call last)
<ipython-input-6-d3b52907284c> in <module>()
—-> 1 arr.repeat([2,3,4])ValueError: operands could not be broadcast together with shape (12,) (3,)
c:rp_arr長度和數組arr長度相等
In [7]: arr.repeat(np.arange(12)) Out[7]: array([ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11])
d:rp_arr長度大於數組arr長度,也無法廣播,報錯
In [8]: arr.repeat(np.arange(13))
—————————————————————————
ValueError Traceback (most recent call last)
<ipython-input-8-ec8454224d1b> in <module>()
—-> 1 arr.repeat(np.arange(13))ValueError: operands could not be broadcast together with shape (12,) (13,)
結論:兩個數組滿足廣播的條件是兩個數組的後緣維度(即從末尾開始算起的維度)的軸長度相等或其中一方的長度為1
③repeats為整數N,axis=M:數組arr的軸M上的每個元素重復N次,M=-1代表最後一條軸
In [9]: arr.repeat(2,axis=0) Out[9]: array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]], [[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]]) In [12]: arr.repeat(2,axis=-1)#arr.repeat(2,axis=-1)等同於arr.repeat(2,axis=2) Out[12]: array([[[ 0, 0, 1, 1, 2, 2], [ 3, 3, 4, 4, 5, 5], [ 6, 6, 7, 7, 8, 8], [ 9, 9, 10, 10, 11, 11]]])
④repeats為整數數組rp_arr,axis=M:把數組arr1軸M上的元素依次重復對應rp_arr數組中元素對應次數。若rp_arr為一個值的一維數組,則數組arr1軸M上的各個元素重復相同次數,否則rp_arr數組長度必須和數組arr1軸M的長度相等,否則報錯
a:rp_arr長度和數組arr1軸M上長度相等
在軸0上擴充數組元素
In [13]: arr1 = np.arange(24).reshape(4,2,3) In [14]: arr1 Out[14]: 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]]]) In [15]: arr1.repeat((1,2,3,4),axis=0) Out[15]: array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]], [[ 6, 7, 8], [ 9, 10, 11]], [[12, 13, 14], [15, 16, 17]], [[12, 13, 14], [15, 16, 17]], [[12, 13, 14], [15, 16, 17]], [[18, 19, 20], [21, 22, 23]], [[18, 19, 20], [21, 22, 23]], [[18, 19, 20], [21, 22, 23]], [[18, 19, 20], [21, 22, 23]]])
在軸1上擴充數組元素
In [19]: arr1.repeat([1,2],axis=1) Out[19]: array([[[ 0, 1, 2], [ 3, 4, 5], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11], [ 9, 10, 11]], [[12, 13, 14], [15, 16, 17], [15, 16, 17]], [[18, 19, 20], [21, 22, 23], [21, 22, 23]]])
b:rp_arr為單值數組時,進行廣播
In [20]: arr1.repeat([2],axis=0) Out[20]: array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]], [[ 6, 7, 8], [ 9, 10, 11]], [[12, 13, 14], [15, 16, 17]], [[12, 13, 14], [15, 16, 17]], [[18, 19, 20], [21, 22, 23]], [[18, 19, 20], [21, 22, 23]]])
c:rp_arr和數組arr1某軸不滿足廣播條件,則報錯
In [21]: arr1.repeat((1,2,3),axis=0)
—————————————————————————
ValueError Traceback (most recent call last)
<ipython-input-21-8ae4dc97e410> in <module>()
—-> 1 arr1.repeat((1,2,3),axis=0)ValueError: operands could not be broadcast together with shape (4,) (3,)
tile函數兩個作用:①擴充數組元素 ②提升數組維度
numpy.tile(A, reps):根據reps中元素擴充數組A中對應軸上的元素
①reps為整數N:可以把整數N理解成含一個元素N的序列reps,若數組.ndim大於reps序列的長度,則需在reps序列的索引為0的位置開始添加元素1,直到reps的長度和數組的維度數相等,然後數組各軸上的元素依次重復reps序列中元素對應的次數
對於一維數組而言:是整體數組重復N次,從數組的最後一位置開始重復,註意與repeat函數的區別
In [26]: arr3 = np.arange(4) In [27]: arr3 Out[27]: array([0, 1, 2, 3]) In [28]: np.tile(arr3,2) Out[28]: array([0, 1, 2, 3, 0, 1, 2, 3])
對多維數組而言:arr2.ndim=3,,reps=[2,],可以看出數組的長度大於序列reps的長度,因此需要向reps中添加元素,變成reps=[1,1,2],然後arr2數組再根據reps中的元素重復其對應軸上的元素,reps=[1,1,2]代表數組arr2在軸0上各個元素重復1次,在軸1上的各個元素重復1次,在軸1上的各個元素重復2次
In [29]: arr2 = np.arange(24).reshape(4,2,3) In [30]: arr2 Out[30]: 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]]]) In [31]: np.tile(arr2,2) Out[31]: array([[[ 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5]], [[ 6, 7, 8, 6, 7, 8], [ 9, 10, 11, 9, 10, 11]], [[12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17]], [[18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23]]])
②reps為整數序列rp_arr:若數組.ndim大於rp_arr長度,方法同①相同,若數組ndim小於rp_arr長度,則需在數組的首緣維添加新軸,直到數組的維度數和rp_arr長度相等,然後數組各軸上的元素依次重復reps序列中元素對應的次數
a:數組維度大於rp_arr長度:需rp_arr提升為(1,2,3)
In [33]: arr2 = np.arange(24).reshape(4,2,3) In [34]: arr2 Out[34]: 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]]]) In [35]: np.tile(arr2,(2,3)) Out[35]: array([[[ 0, 1, 2, 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5, 3, 4, 5], [ 0, 1, 2, 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5, 3, 4, 5]], [[ 6, 7, 8, 6, 7, 8, 6, 7, 8], [ 9, 10, 11, 9, 10, 11, 9, 10, 11], [ 6, 7, 8, 6, 7, 8, 6, 7, 8], [ 9, 10, 11, 9, 10, 11, 9, 10, 11]], [[12, 13, 14, 12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17, 15, 16, 17], [12, 13, 14, 12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17, 15, 16, 17]], [[18, 19, 20, 18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23, 21, 22, 23], [18, 19, 20, 18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23, 21, 22, 23]]])
b:數組的維度小於rp_arr的長度:需在數組的首緣維度新增加一條軸,使其shape變為(1,4,2,3)
In [36]: np.tile(arr2,(2,1,1,3)) Out[36]: array([[[[ 0, 1, 2, 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5, 3, 4, 5]], [[ 6, 7, 8, 6, 7, 8, 6, 7, 8], [ 9, 10, 11, 9, 10, 11, 9, 10, 11]], [[12, 13, 14, 12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17, 15, 16, 17]], [[18, 19, 20, 18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23, 21, 22, 23]]], [[[ 0, 1, 2, 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5, 3, 4, 5]], [[ 6, 7, 8, 6, 7, 8, 6, 7, 8], [ 9, 10, 11, 9, 10, 11, 9, 10, 11]], [[12, 13, 14, 12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17, 15, 16, 17]], [[18, 19, 20, 18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23, 21, 22, 23]]]])
numpy的repeat和tile 用來復制數組
repeat和tile都可以用來復制數組的,但是有一些區別
關鍵區別在於repeat是對於元素的復制,tile是以整個數組為單位的 ,repeat復制時元素依次復制,註意不要用錯,區別類似於[1,1,2,2]和[1,2,1,2]
repeat
用法
np.repeat(a, repeats, axis=None)
重復復制數組a的元素,元素的定義與axis有關,axis不指定時,數組會被展開進行復制,每個元素就是一個值,指定axis時,就是aixis指定維度上的一個元素
a = np.array([[1,2], [3,4]])
不指定axis,默認None,這時候數組會被展開成1維,再進行復制
np.repeat(a, 2) # 所有元素依次復制相同的次數
參數是列表
np.repeat(a, [1, 2, 1, 2]) # 如果第二個參數是列表,列表長度必須和a的復制可選元素數目相等,這裡都是4
指定axis
指定時,就是指定瞭復制元素沿的維度,這時候就不會把數組展平,會維持原來的維度數
np.repeat(a, 2, axi=0) # 所有沿著0維的元素依次復制相同的次數
np.repeat(a, [1, 2], axis=1) # 第二個參數是列表,列表長度必須和a的復制可選元素數目相等,這裡是2
結果如下,復制元素從第1維度算,可以看到第一列被復制瞭一次,第二列被復制瞭兩次
tile
用法
np.tile(a, repeats)
復制數組,repeats可以是整數或者元組、數組
repeats是整數
示例如下,它會將數組復制兩份,並且在最後一維將兩個元素疊加在一起,數組的維數不變,最後一維根據復制次數加倍
repeats是列表或元組
如果列表長度是1,和整數時相同。
列表長度不為1時,列表從後向前看,最後一項是2,所以復制兩個數組,在最後一維進行疊加,倒數第二項是3,將前步的結果進行復制,並在倒數第二維,結果如下
當列表的長度超過數組的維數時,和前面類似,從後向前復制,復制結果會增加維度與列表的維數匹配,結果如下,在上面的基礎上,增加瞭一維
復制結果的shape
但是對於 簡單的單個數組重復,個人更喜歡使用stack和concatenate將同一個數組堆疊起來
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Numpy中的repeat函數使用
- python基礎知識之索引與切片詳解
- Python Numpy中ndarray的常見操作
- Python數組變形的幾種實現方法
- numpy的squeeze函數使用方法