Numpy/TensorFlow - OPs 小记: np.repeat 和 np.tile

Numpy 和 TensorFlow 中 repeat()tile() 都能对输入数组进行重复, 那么它们的区别是什么呢? 本小节将以numpy为例详细介绍它们.

(tensorflow的版本与numpy的完全相同.)


np.repeat()

将数组 a 中的元素重复 repeats 次.

  • 注意: 重复的是a中的元素, 最终返回展平的(flattened)数组, 或其维度与 a 相同.

  • 函数定义:

    def repeat(a, repeats, axis=None):
        """
        Repeat elements of an array.
    
        Parameters
        ----------
        a : array_like
            Input array.
        repeats : int or array of ints
            The number of repetitions for each element.  `repeats` is broadcasted
            to fit the shape of the given axis.
        axis : int, optional
            The axis along which to repeat values.  By default, use the
            flattened input array, and return a flat output array.
        """
    
  • 说明:

  1. 参数 repeats 表示元素被重复的次数, 可以是 int, 也可以是 int array. 如果是 int array, 那么它必须可以在 axis 方向上进行 广播 (broadcasting)

    注: 如果读者还不太明白 broadcasting, 强烈建议读者把其弄明白后再往下学习此文)

  2. 参数 axis 表示在指定轴方向上进行重复, int类型. 给定的轴方向必须存在, 否则报错.

下面以几个示例加以说明:

  • repeatsint 类型, 每个元素被重复 repeats
>>> a = np.array([1,2,3])         # 1维数组
>>> np.repeat(a, 2)	              # axis=None; 默认返回展平后的数组
>>> array([1, 1, 2, 2, 3, 3])

>>> b = np.array([[1,2], [3,4]])  # 2维数组
>>> np.repeat(b, 2)	              # axis=None; 默认返回展平后的数组
>>> array([1, 1, 2, 2, 3, 3, 4, 4])

>>> np.repeat(b, 2, axis=0) 	  # axis=0; 元素在0轴上重复2次
>>> array([[1, 2],				  # 注: 在0轴上, 元素为 [1,2] 和 [3, 4]
	       [1, 2],				  
	       [3, 4],
	       [3, 4]])

>>> np.repeat(b, 2, axis=1)		  # axis=1; 元素在1轴上重复2次
>>> array([[1, 1, 2, 2],		  # 注: 在1轴上, 元素为 [1, 3] 和 [2, 4]
       	   [3, 3, 4, 4]])
  • repeatsint array 类型, 则repeats 必须能在给定 axis广播
>>> a = np.array([[1,2],[3,4])  # 2维数组
>>> np.repeat(a, [1,2])         # 报错:默认展平数组[shape=(4,)], 而repeats[shape=(2,)], 广播失败 

>>> np.repeat(a, [1,2], axis=0) # axis=0; repeats[shape=(2,)]在0轴上[shape=(2,)]广播
>>> array([[1, 2],              # 广播后repeats=[1,2], 因此在0轴上对应元素重复[1次, 2次]
           [3, 4],
           [3, 4]])

>>> np.repeat(a, [1,2], axis=1) # axis=1; 同理, repeats在1轴上[shape=(2,)]广播
>>> array([[1, 2, 2],           # 广播后repeats=[1,2], 因此在1轴上对应元素重复[1次, 2次]
           [3, 4, 4]])          # 注: 1轴上对应元素为 [1, 3] 和 [2, 4]

np.tile()

将数组 A 重复reps

  • 注意: 重复的是数组 A 这个整体(想像一下场景: 把 A 看成一个 tile (瓦片), 根据 reps 在不同的轴(方向)上进行重复铺设)

np.tile()
(Online Image from link)

  • 函数定义:
def tile(A, reps):
    """
    Construct an array by repeating A the number of times given by reps.
    
    If `reps` has length ``d``, the result will have dimension of
    ``max(d, A.ndim)``.
    
	If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new
    axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication,
    or shape (1, 1, 3) for 3-D replication. If this is not the desired
    behavior, promote `A` to d-dimensions manually before calling this
    function.

    If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it.
    Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as
    (1, 1, 2, 2).
    
	Parameters
    ----------
    A : array_like
        The input array.
    reps : array_like
        The number of repetitions of `A` along each axis.

	Returns
    -------
    c : ndarray
        The tiled output array.
    """
  • 说明:
  1. 参数 repsintint array, 表示在指定维度上重复的次数
  2. 参数 Areps 将根据 A.ndimlen(reps) 进行改变, 函数定义中已作了详细说明, 请参见示例进一步理解
  3. 返回 c 的维度为 A.ndimlen(reps) 中较大的那一个

下面是具体示例, 需注意每个实例中 repsA 的变化情况:

  • repsint 类型. 此时很好理解, 将 A 重复 reps 次, 但要视 A 的维度决定该如何重复.
>>> A = np.array([1,2,3])     	# 1维数组
>>> np.tile(A, 2)			  	# reps=2,等价于reps=[2]; 此时A.ndim == len(reps)
>>> array([1, 2, 3, 1, 2, 3] 	# A和reps无须改变, 将A在0轴上重复2次

>>> A = np.array([[1,2],[3,4]]) # 2维数组
>>> np.tile(A, 2)				# resp=2,等价于reps=[2]; 此时A.ndim > len(reps)
>>> array([[1, 2, 1, 2],		# reps改变:在前面补1, 使得A.ndim == len(reps), 即
           [3, 4, 3, 4]])       # reps=[1,2], 最终将A在0轴和1轴上分别重复[1次, 2次]

# 对于3维和更高维度也一样, 读者可以自己尝试
  • repsint array 类型, 其中每个元素代表每个轴上应该重复的次数
>>> A = np.array([1,2,3])    	# 1维数组
>>> np.tile(A, [2,2])			# reps=[2,2]; 此时A.ndim < len(reps)
>>> array([[1, 2, 3, 1, 2, 3],  # A的shape改变:在其前面补1, 使得A.ndim == len(reps), 即
           [1, 2, 3, 1, 2, 3]]) # A=[[1,2,3]], 最终将A在0轴和1轴上分别重复[2次, 2次]

>>> A = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])   
>>> A 
>>> array([[[1, 2],             # 3维数组
            [3, 4]],
            
           [[5, 6],
            [7, 8]]])
>>> np.tile(A, [2,2])  			# reps=[2,2]; 此时A.ndim > len(reps)
>>> array([[[1, 2, 1, 2],       # reps改变, 在其前面补1, 变为 reps=[1, 2, 2]
            [3, 4, 3, 4],       # 因此最终结果为:
            [1, 2, 1, 2],       # A在0轴,1轴,2轴上分别重复[1次,2次,2次]
            [3, 4, 3, 4]],
            
           [[5, 6, 5, 6],
            [7, 8, 7, 8],
            [5, 6, 5, 6],
            [7, 8, 7, 8]]])

后记:
在使用 np.tile() 时, 不管是 A 的改变, 还是 reps 改变, 都特别容易让人迷糊. 因此, 为了方便, 直接传入与 A 维度相同的长度的 pres 即可, 这样就能很清楚的明白在哪个维度上重复多少次了, 例如: np.tile(A, [2, 2, 2]) 表示将 A 在 0,1,2 轴全部重复2次.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值