无需修改原始对象就可以调整Numpy大小

2024-03-29 08:54:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我想扩展两个表的维度,这样我就可以在它们上使用numpy的广播乘法。我使用了以下代码:

def tableResize(table1,table2,var1,var2):
    n1=[1]*len(var1)
    n2=[1]*len(var2)
    table1.resize(list(table1.shape)+n2)
    table2.resize(n1+list(table2.shape))
    return table1,table2

假设表1是2*3,表2是3*4,展开的表将是2*3*1*1和1*1*3*4。 虽然我注意到我会写字

^{pr2}$

这不会对表1和表2本身产生任何影响。但是我不知道如何自动生成列表[:,:,np.newaxis,np.newaxis]。在

但是,resize方法没有返回值,它将修改对象本身。我不想用深拷贝。有人有主意吗?非常感谢^


Tags: 代码numpylennplistshape乘法n2
1条回答
网友
1楼 · 发布于 2024-03-29 08:54:31

a1 = a.reshape(...)返回视图-a1具有新形状,但共享数据缓冲区。在

a1 = table1.reshape(table1.shape+(1,)*table2.ndim)
 # (2, 3, 1, 1)

b1 = table2.reshape((1,)*table1.ndim+table2.shape)
 # (1, 1, 3, 4)

{start}不需要在cd3}处展开,{。在

^{pr2}$

看看np.atleast_3dnp.broadcast_arrays,了解如何扩展数组的维数。在


进一步看一下resize,我想说,无论是哪种形式,当您只想添加单例维度时,它都是使用错误的函数。reshape是正确的函数/方法。或者是np.newaxis。在


您可以通过连接切片和None来构建[:,:,np.newaxis,np.newaxis]

s=[slice(None)]*2 + [None]*2
# [slice(None, None, None), slice(None, None, None), None, None]

table1[s].shape
# (2, 3, 1, 1)

np.resize代码:

File:        /usr/lib/python3/dist-packages/numpy/core/fromnumeric.py
def resize(a, new_shape):

    if isinstance(new_shape, (int, nt.integer)):
        new_shape = (new_shape,)
    a = ravel(a)
    Na = len(a)
    if not Na: return mu.zeros(new_shape, a.dtype.char)
    total_size = um.multiply.reduce(new_shape)
    n_copies = int(total_size / Na)
    extra = total_size % Na

    if total_size == 0:
        return a[:0]

    if extra != 0:
        n_copies = n_copies+1
        extra = Na-extra

    a = concatenate( (a,)*n_copies)
    if extra > 0:
        a = a[:-extra]

    return reshape(a, new_shape)

np.reshape代码(典型的函数委托给数组方法):

File:        /usr/lib/python3/dist-packages/numpy/core/fromnumeric.py
def reshape(a, newshape, order='C'):
    try:
        reshape = a.reshape
    except AttributeError:
        return _wrapit(a, 'reshape', newshape, order=order)
    return reshape(newshape, order=order)

比较两个函数的计时-resize要慢得多。在

In [109]: timeit np.resize(a,(2,3,1,1)).shape
10000 loops, best of 3: 41.5 µs per loop

In [110]: timeit np.reshape(a,(2,3,1,1)).shape
100000 loops, best of 3: 2.79 µs per loop

就地resize速度很快:

In [124]: %%timeit a1=a.copy()
a1.resize((2,3,1,1))
a1.shape
   .....: 
1000000 loops, best of 3: 799 ns per loop
网友
2楼 · 发布于 2024-03-29 08:54:31

However, the resize method doesn't have return value and it will modify the object itself.

是的,但是如果你看the docs for the ^{} method,它会给你答案:^{} function。在

在NumPy中有很多这样的对,其中np.spam(a, eggs)生成{}的spamified副本,而{}spamifiesa在适当的位置。如果你看一下这些文档,它们会链接在一起。在

所以,我想你想要的是:

t1 = np.resize(table1, list(table1.shape)+n2)
t2 = np.resize(table2, n1+list(table2.shape))
return t1, t2

相关问题 更多 >