2015-06-11 41 views
5

在Matlab中,我能做到以下几点:简单的方法来折叠numpy数组的尾部尺寸?

X = randn(25,25,25); 
size(X(:,:)) 

ans = 
    25 625 

我经常发现自己想要迅速崩溃数组的尾部尺寸,不知道如何在numpy的做到这一点。

我知道我能做到这一点:

In [22]: x = np.random.randn(25,25,25) 
In [23]: x = x.reshape(x.shape[:-2] + (-1,)) 
In [24]: x.shape 
Out[24]: (25, 625) 

x.reshape(x.shape[:-2] + (-1,))很多不够简明(和需要大约x详细信息),比简单地做x(:,:)

我明明试过类似numpy的索引,但希望不工作:

In [25]: x = np.random.randn(25,25,25) 
In [26]: x[:,:].shape 
Out[26]: (25, 25, 25) 

如何崩溃数组的尾部尺寸以简洁的方式任何提示?

编辑:请注意,我是在产生的数组本身之后,而不仅仅是它的形状。在上面的例子中,我只使用size()x.shape来表示数组是什么样的。

+0

在附注中,您的示例不正确......'x.shape [: - 2]'会产生一个空元组。 (给它加'-1'意味着该数组将被“扁平化”成15625长度的数组)。我猜你的意思是'x.shape [0]'? –

+0

@JoeKington:它*是*正确的(尝试它)。 'x.shape [: - 2]'返回'x.shape'直到(但不包括)倒数第二个元素。所以对于一个3D数组'x',它只返回'x.shape'的第一个元素。我使用'[:-2]'而不是'[0]',因为我正在寻找一种适用于N> 2的所有ND阵列的通用解决方案。 – EelkeSpaak

+0

@ElkeSpaak - 对。我没有清楚地思考。 –

回答

3

4d或更高版本应该会发生什么?

octave:7> x=randn(25,25,25,25); 
octave:8> size(x(:,:)) 
ans = 
     25 15625 

您的(:,:)将其缩小到2个维度,合并最后的维度。最后一个维度是MATLAB自动添加和折叠维度的地方。

In [605]: x=np.ones((25,25,25,25)) 

In [606]: x.reshape(x.shape[0],-1).shape # like Joe's 
Out[606]: (25, 15625) 

In [607]: x.reshape(x.shape[:-2]+(-1,)).shape 
Out[607]: (25, 25, 625) 

reshape例如做一些事情从MATLAB不同,它只是崩溃的最后2倒塌下来到2个维度像MATLAB是一种更简单的表达。

MATLAB简洁是因为您的需求与其假设相匹配。该numpy相当于不是那么简洁,但给你更多的控制

例如保留最后一个维度,或通过结合2维2:

In [608]: x.reshape(-1,x.shape[-1]).shape 
Out[608]: (15625, 25) 
In [610]: x.reshape(-1,np.prod(x.shape[-2:])).shape 
Out[610]: (625, 625) 

什么是相当于MATLAB?

octave:24> size(reshape(x,[],size(x)(2:end))) 
ans = 
15625  25 
octave:31> size(reshape(x,[],prod(size(x)(3:end)))) 
1

可以使用np.hstack

>>> np.hstack(x).shape 
(25, 625) 

np.hstack AKE阵列序列和水平堆叠起来​​,使单个阵列。

+1

这是'np.hstack'的一个有趣的用法!但是,它不会产生与'x.reshape(x.shape [: - 2] +(-1,)''相同的结果,因此应谨慎使用。再想一想,我相信会发生的事情是'np.hstack'将数组的* first *维视为可迭代维,因此返回与'np.hstack(x [0,: ,:],X [1:,:],...)'。我需要的功能使得第一个维度不受影响(即以前在x [0,:,]中的所有数据现在都在x [0 ,:]中),正如Matlab版本的情况一样。 – EelkeSpaak

+0

你想要一个新的数组还是只想要它的形状? – Kasramvd

+0

我在数组本身的内容之后,其形状仅用于说明。我编辑了原始问题,使其更加清晰。 – EelkeSpaak

1

您可能会发现它更简洁直接修改shape属性。例如:

import numpy as np 

x = np.random.randn(25, 25, 25) 
x.shape = x.shape[0], -1 

print x.shape 
print x 

这在功能上等效于reshape(在数据排序等的意义上)。显然,它仍然需要关于x的形状的相同信息,但它是处理重塑的更简洁的方式。

+1

它有附加的“好处”,如果重塑不能没有副本,它会引发一个错误,所以我经常使用它作为声明我的代码有效使用内存的一种形式。 – Jaime