Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy.tile非整数次_Python_Arrays_Numpy - Fatal编程技术网

Python numpy.tile非整数次

Python numpy.tile非整数次,python,arrays,numpy,Python,Arrays,Numpy,在numpy中是否有更好的方法将数组平铺非整数次?这就完成了任务,但很笨重,不容易推广到n维: import numpy as np arr = np.arange(6).reshape((2, 3)) desired_shape = (5, 8) reps = tuple([x // y for x, y in zip(desired_shape, arr.shape)]) left = tuple([x % y for x, y in zip(desired_shape, arr.shape

numpy
中是否有更好的方法将数组平铺非整数次?这就完成了任务,但很笨重,不容易推广到n维:

import numpy as np
arr = np.arange(6).reshape((2, 3))
desired_shape = (5, 8)
reps = tuple([x // y for x, y in zip(desired_shape, arr.shape)])
left = tuple([x % y for x, y in zip(desired_shape, arr.shape)])
tmp = np.tile(arr, reps)
tmp = np.r_[tmp, tmp[slice(left[0]), :]]
tmp = np.c_[tmp, tmp[:, slice(left[1])]]
这将产生:

array([[0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1]])

编辑:绩效结果

对推广到n维的三个答案的一些检验。这些定义被放入一个文件
newfile.py

import numpy as np

def tile_pad(a, dims):
    return np.pad(a, tuple((0, i) for i in (np.array(dims) - a.shape)),
                  mode='wrap')

def tile_meshgrid(a, dims):
    return a[np.meshgrid(*[np.arange(j) % k for j, k in zip(dims, a.shape)],
                         sparse=True, indexing='ij')]

def tile_rav_mult_idx(a, dims):
    return a.flat[np.ravel_multi_index(np.indices(dims), a.shape, mode='wrap')]
下面是bash语句:

python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_pad(np.arange(30).reshape(2, 3, 5), (3, 5, 7))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_meshgrid(np.arange(30).reshape(2, 3, 5), (3, 5, 7))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_rav_mult_idx(np.arange(30).reshape(2, 3, 5), (3, 5, 7))'

python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_pad(np.arange(2310).reshape(2, 3, 5, 7, 11), (13, 17, 19, 23, 29))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_meshgrid(np.arange(2310).reshape(2, 3, 5, 7, 11), (13, 17, 19, 23, 29))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_rav_mult_idx(np.arange(2310).reshape(2, 3, 5, 7, 11), (13, 17, 19, 23, 29))'
以下是小阵列(2 x 3 x 5)的结果:

以下是较大阵列(2 x 3 x 5 x 7 x 11)的结果:

<> P> >使用<代码> NP.PAD可能是性能最好的选择。

不确定N维,但可以考虑使用<代码> HStAt/<代码>和<代码> V堆栈。p>

arr = np.arange(6).reshape((2, 3))

nx, ny = shape(arr)
Nx, Ny = 5, 8 # These are the new shapes
iX, iY = Nx//nx+1, Ny//ny+1

result = vstack(tuple([ hstack(tuple([arr]*iX))[:, :Nx] ]*iY))[:Ny, :  ]

有一个
dstack
,但我怀疑这是否有用。不完全确定3维或更高维

这里有一个非常简洁的方法:

In [57]: a
Out[57]: 
array([[0, 1, 2],
       [3, 4, 5]])

In [58]: old = a.shape

In [59]: new = (5, 8)

In [60]: a[(np.arange(new[0]) % old[0])[:,None], np.arange(new[1]) % old[1]]
Out[60]: 
array([[0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1]])

这是一个n维的概括:

def rep_shape(a, shape):
    indices = np.meshgrid(*[np.arange(k) % j for j, k in zip(a.shape, shape)],
                          sparse=True, indexing='ij')
    return a[indices]
例如:

In [89]: a
Out[89]: 
array([[0, 1, 2],
       [3, 4, 5]])

In [90]: rep_shape(a, (5, 8))
Out[90]: 
array([[0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1]])

In [91]: rep_shape(a, (4, 2))
Out[91]: 
array([[0, 1],
       [3, 4],
       [0, 1],
       [3, 4]])

In [92]: b = np.arange(24).reshape(2,3,4)

In [93]: b
Out[93]: 
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 [94]: rep_shape(b, (3,4,5))
Out[94]: 
array([[[ 0,  1,  2,  3,  0],
        [ 4,  5,  6,  7,  4],
        [ 8,  9, 10, 11,  8],
        [ 0,  1,  2,  3,  0]],

       [[12, 13, 14, 15, 12],
        [16, 17, 18, 19, 16],
        [20, 21, 22, 23, 20],
        [12, 13, 14, 15, 12]],

       [[ 0,  1,  2,  3,  0],
        [ 4,  5,  6,  7,  4],
        [ 8,  9, 10, 11,  8],
        [ 0,  1,  2,  3,  0]]])

下面是第一个示例的工作原理

其思想是使用数组来索引
a
。看看np.arange(新[0]%旧[0]):

该数组中的每个值都给出了要在结果中使用的
a
行。同样地

In [62]: np.arange(new[1]) % old[1]
Out[62]: array([0, 1, 2, 0, 1, 2, 0, 1])
给出要在结果中使用的
a
列。为了让这些索引数组创建二维结果,我们必须将第一个索引数组重塑为列:

In [63]: (np.arange(new[0]) % old[0])[:,None]
Out[63]: 
array([[0],
       [1],
       [0],
       [1],
       [0]])
当数组用作索引时,它们会广播。以下是广播索引的外观:

n [65]: i, j = np.broadcast_arrays((np.arange(new[0]) % old[0])[:,None], np.arange(new[1]) % old[1])

In [66]: i
Out[66]: 
array([[0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 0, 0, 0]])

In [67]: j
Out[67]: 
array([[0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1]])
以下是生成形状为(5,8)的数组所需的索引数组:

当索引数组如开始时的示例所示(即在第一个索引槽中使用
(np.arange(new[0])%old[0])[:,None]
)时,numpy实际上不会像我在
i
j
中那样在内存中生成这些索引数组
i
j
显示广播时的有效内容


函数
rep_shape
做了同样的事情,使用
np.meshgrid
为每个“槽”生成具有正确形状的索引数组以进行广播。

可能不是很有效,但非常简洁:

arr = np.arange(6).reshape((2, 3))
desired_shape = (5, 8)

arr.flat[np.ravel_multi_index(np.indices(desired_shape), arr.shape, mode='wrap')]

另一个更简洁的解决方案:

arr = np.arange(6).reshape((2, 3))
desired_shape = np.array((5, 8))

pads = tuple((0, i) for i in (desired_shape-arr.shape))
# pads = ((0, add_rows), (0, add_columns), ...)
np.pad(arr, pads, mode="wrap")

但对于小型阵列来说速度较慢(但对于大型阵列来说速度要快得多)。奇怪的是,np.pad不接受np.array作为pad。

当使用非整数的
np.tile()
时,行为应该如何?@saulocastro:也许我的标题有点误导。在我看来,
np.tile
不应该将非整数参数带到
reps
。我想要实现的类似于如果
np.tile
将非整数参数带到
reps
并且如果传递的非整数在输出数组中产生整数行/列/etc,将会发生什么。我所知道的最接近的类似示例是
R
language.Nice中
rep()
函数的
length.out
参数。就我所知,也可以推广到n维:使用
arr=np.arange(30)进行测试。重塑((2,3,5))
所需的形状=(5,8,13)
这非常有效。一个潜在的缺点是,在n维情况下,
np.索引(所需的_形状)
创建了一个临时数组,其形状
(n,)+所需的_形状
(例如,
所需的_形状
为(5,8,13)时为(3,5,8,13))。但如果阵列很小,这就不是问题。
n [65]: i, j = np.broadcast_arrays((np.arange(new[0]) % old[0])[:,None], np.arange(new[1]) % old[1])

In [66]: i
Out[66]: 
array([[0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 0, 0, 0]])

In [67]: j
Out[67]: 
array([[0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [0, 1, 2, 0, 1, 2, 0, 1]])
In [68]: a[i,j]
Out[68]: 
array([[0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1],
       [3, 4, 5, 3, 4, 5, 3, 4],
       [0, 1, 2, 0, 1, 2, 0, 1]])
arr = np.arange(6).reshape((2, 3))
desired_shape = (5, 8)

arr.flat[np.ravel_multi_index(np.indices(desired_shape), arr.shape, mode='wrap')]
arr = np.arange(6).reshape((2, 3))
desired_shape = np.array((5, 8))

pads = tuple((0, i) for i in (desired_shape-arr.shape))
# pads = ((0, add_rows), (0, add_columns), ...)
np.pad(arr, pads, mode="wrap")