关于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将同一个数组堆叠起来
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。