2016-03-15 191 views
9

numpy結果數組的維數在運行時會有所不同。 1列數組和1列數組經常混淆。 在一種情況下,我可以遍歷列,在另一種情況下,我不能。Numpy重塑1d到2d陣列,1列

你如何優雅地解決這個問題? 爲了避免我的代碼充斥if報表維度檢查,我使用此功能:

def reshape_to_vect(ar): 
    if len(ar.shape) == 1: 
     return ar.reshape(ar.shape[0],1) 
    return ar 

但是,這感覺不太優雅而昂貴。有更好的解決方案嗎?

+0

什麼是'dtype'?看起來'結構化'。 – hpaulj

+0

這是無關緊要的,我只是用它作爲我如何以1d或2d數組結束的例子。我的問題是關於如何系統地優雅地將1d轉換爲2d數組。 – DevShark

回答

7

你可以這樣做 -

ar.reshape(ar.shape[0],-1) 

這第二個輸入reshape-1花費的第二軸的元素數量的照顧。因此,對於2D輸入案例,它沒有改變。對於1D輸入案例,由於ar.shape[0](它是元素的總數),它會創建一個2D數組,其中所有元素都被「推送」到第一個軸,因爲ar.shape[0]是元素的總數。

樣品試驗

1D案例:

In [87]: ar 
Out[87]: array([ 0.80203158, 0.25762844, 0.67039516, 0.31021513, 0.80701097]) 

In [88]: ar.reshape(ar.shape[0],-1) 
Out[88]: 
array([[ 0.80203158], 
     [ 0.25762844], 
     [ 0.67039516], 
     [ 0.31021513], 
     [ 0.80701097]]) 

2D案例:

In [82]: ar 
Out[82]: 
array([[ 0.37684126, 0.16973899, 0.82157815, 0.38958523], 
     [ 0.39728524, 0.03952238, 0.04153052, 0.82009233], 
     [ 0.38748174, 0.51377738, 0.40365096, 0.74823535]]) 

In [83]: ar.reshape(ar.shape[0],-1) 
Out[83]: 
array([[ 0.37684126, 0.16973899, 0.82157815, 0.38958523], 
     [ 0.39728524, 0.03952238, 0.04153052, 0.82009233], 
     [ 0.38748174, 0.51377738, 0.40365096, 0.74823535]]) 
+1

這個答案的一個變體是:'x = np.reshape(x,(len(x), - 1))',它也處理輸入是1d或2d列表的情況。 –

+0

@LucaCiti使這個單獨的答案,所以我可以投它。 –

+0

完成。感謝您的推薦。 –

0

我問dtype因爲你的榜樣是令人費解。

我能夠與3個元素(1D)和3個字段的結構化陣列:

In [1]: A = np.ones((3,), dtype='i,i,i') 
In [2]: A 
Out[2]: 
array([(1, 1, 1), (1, 1, 1), (1, 1, 1)], 
     dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')]) 

我可以按名稱訪問一個場(添加括號不改變的東西)

In [3]: A['f0'].shape 
Out[3]: (3,) 

但如果我獲得2場,我仍然得到一維數組

In [4]: A[['f0','f1']].shape 
Out[4]: (3,) 
In [5]: A[['f0','f1']] 
Out[5]: 
array([(1, 1), (1, 1), (1, 1)], 
     dtype=[('f0', '<i4'), ('f1', '<i4')]) 

其實這些額外的支架做的事,如果我LOO處的K值

In [22]: A['f0'] 
Out[22]: array([1, 1, 1], dtype=int32) 
In [23]: A[['f0']] 
Out[23]: 
array([(1,), (1,), (1,)], 
     dtype=[('f0', '<i4')]) 

如果數組是一個簡單的2D一個,我還沒有得到你的形狀

In [24]: A=np.ones((3,3),int) 
In [25]: A[0].shape 
Out[25]: (3,) 
In [26]: A[[0]].shape 
Out[26]: (1, 3) 
In [27]: A[[0,1]].shape 
Out[27]: (2, 3) 

但至於製作的問題,確保陣列是2D,不管是否索引返回維或2,你的功能基本上確定

def reshape_to_vect(ar): 
    if len(ar.shape) == 1: 
     return ar.reshape(ar.shape[0],1) 
    return ar 

您可以測試ar.ndim而不是len(ar.shape)。但是無論如何,這不是代價高昂的 - 也就是說,執行時間很短 - 沒有大的數組操作。 reshape不會複製數據(除非您的步幅很奇怪),所以這只是使用共享數據指針創建新數組對象的成本。

看代碼np.atleast_2d;它測試0d和1d。在1d的情況下,它返回result = ary[newaxis,:]。它首先添加額外的軸,更加自然的添加軸的位置numpy。最後添加它。

ar.reshape(ar.shape[0],-1)是一種繞過if測試的巧妙方法。在小時序測試中速度更快,但我們正在談論微秒,函數調用層的影響。

np.column_stack是另一個函數,在需要時創建列數組。它使用:

if arr.ndim < 2: 
     arr = array(arr, copy=False, subok=True, ndmin=2).T 
+0

好的,我刪除了這個例子。我試圖給出一個具體的例子,但如果它很混亂,最好不要擁有它。 – DevShark

0

爲了避免需要擺在首位,以重塑,如果你切與列表行/列,或「跑」片,你會得到一個二維數組有一個行/列

import numpy as np 
x = np.array(np.random.normal(size=(4,4))) 
print x, '\n' 

Result: 
[[ 0.01360395 1.12130368 0.95429414 0.56827029] 
[-0.66592215 1.04852182 0.20588886 0.37623406] 
[ 0.9440652 0.69157556 0.8252977 -0.53993904] 
[ 0.6437994 0.32704783 0.52523173 0.8320762 ]] 

y = x[:,[0]] 
print y, 'col vector \n' 
Result: 
[[ 0.01360395] 
[-0.66592215] 
[ 0.9440652 ] 
[ 0.6437994 ]] col vector 


y = x[[0],:] 
print y, 'row vector \n' 

Result: 
[[ 0.01360395 1.12130368 0.95429414 0.56827029]] row vector 

# Slice with "running" index on a column 
y = x[:,0:1] 
print y, '\n' 

Result: 
[[ 0.01360395] 
[-0.66592215] 
[ 0.9440652 ] 
[ 0.6437994 ]] 

相反,如果你使用一個號碼選擇行/列,它會導致一維數組,這是你的問題的根本原因:

y = x[:,0] 
print y, '\n' 

Result: 
[ 0.01360395 -0.66592215 0.9440652 0.6437994 ] 
4

最簡單的方法:

ar.reshape(-1, 1) 
2

divakar回答的變體是:x = np.reshape(x, (len(x),-1)),它也處理輸入是1d或2d列表的情況。