2015-06-11 82 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