2017-07-28 21 views
6

當參數是列表或元組時,np.c_的輸出有所不同。考慮以下三個行的輸出帶有列表和元組參數的np.c_的行爲

np.c_[[1,2]] 
np.c_[(1,2)] 
np.c_[(1,2),] 

隨着list參數,np.c_返回一個列陣列,如所預期。當參數是一個元組(第二行)時,它返回一個2D行。在元組(第三行)之後,爲第一個調用返回一個列數組後的逗號。

有人可以解釋這種行爲的基本原理嗎?

+0

看看代碼。文件中的這個和其他類/函數('indexing_tricks'?)是一個方便但有趣的編碼。 – hpaulj

回答

4

有2共同使用情況np.c_

  • np.c_可以接受1D陣列喜歡的序列:

    In [98]: np.c_[[1,2],[3,4]] 
    Out[98]: 
    array([[1, 3], 
         [2, 4]]) 
    
  • ,或者np.c_可以接受2D基於陣列的順序喜歡:

    In [96]: np.c_[[[1,2],[3,4]], [[5,6],[7,8]]] 
    Out[96]: 
    array([[1, 2, 5, 6], 
         [3, 4, 7, 8]]) 
    

所以np.c_可以傳遞1D數組或喜歡2D數組。 但是,這引發了一個問題,np.c_應該如何識別輸入是單個2D數組(如[[1,2],[3,4]]還是1D數組類喜歡的序列(例如[1 ,2],[3,4])?

開發人員做出了一個設計決定:如果np.c_傳遞了一個元組,則該參數將被視爲一個單獨的數組喜歡的序列。如果它傳遞了一個非元組(例如一個列表),那麼該對象將被視爲一個單一的數組。

因此,np.c_[[1,2], [3,4]](相當於np.c_[([1,2], [3,4])])將([1,2], [3,4])視爲兩個單獨的1D陣列。

In [99]: np.c_[[1,2], [3,4]] 
Out[99]: 
array([[1, 3], 
     [2, 4]]) 

相反,np.c_[[[1,2], [3,4]]]將把[[1,2], [3,4]]作爲一個單一的2D陣列。

In [100]: np.c_[[[1,2], [3,4]]] 
Out[100]: 
array([[1, 2], 
     [3, 4]]) 

所以,對於實施例你貼:

np.c_[[1,2]]對待[1,2]作爲單一1D陣列狀,所以它使[1,2]爲2D陣列的列:

In [101]: np.c_[[1,2]] 
Out[101]: 
array([[1], 
     [2]]) 

np.c_[(1,2)]對待(1,2)作爲2個獨立的陣列喜歡,所以每個值放置到它自己的柱:

In [102]: np.c_[(1,2)] 
Out[102]: array([[1, 2]]) 

np.c_[(1,2),]對待元組(1,2),(其等同於((1,2),))作爲一個陣列狀的序列,從而使陣列狀被作爲列處理:

In [103]: np.c_[(1,2),] 
Out[103]: 
array([[1], 
     [2]]) 

PS。也許比大多數軟件包都多,NumPy的歷史記錄爲treating lists and tuples differently。該鏈接討論瞭如何將列表和元組傳遞給np.array時的不同處理方式。

2

上處理參數的第一電平來自Python解釋,其轉換一個[...]爲呼叫到__getitem__

In [442]: class Foo(): 
    ...:  def __getitem__(self,args): 
    ...:   print(args) 
    ...:   
In [443]: Foo()['str'] 
str 
In [444]: Foo()[[1,2]] 
[1, 2] 
In [445]: Foo()[[1,2],] 
([1, 2],) 
In [446]: Foo()[(1,2)] 
(1, 2) 
In [447]: Foo()[(1,2),] 
((1, 2),) 

np.c_np.lib.index_tricks.AxisConcatenator一個實例。這是__getitem__

# handle matrix builder syntax 
    if isinstance(key, str): 
     .... 
     mymat = matrixlib.bmat(...) 
     return mymat 

    if not isinstance(key, tuple): 
     key = (key,) 

    .... 
    for k, item in enumerate(key): 
     .... 

所以除了np.bmat兼容的字符串,它把一切投入一個元組,然後在元素上進行迭代。

任何包含[1,2]的變體都與單個元素元組([1,2],)相同。 (1,2)是將被連接的兩個元素。所以是([1,2],[3,4])

請注意,numpy索引也區分列表和元組(儘管有一些不一致)。

In [455]: x=np.arange(24).reshape(2,3,4) 
In [456]: x[0,1]    # tuple - index for each dim 
Out[456]: array([4, 5, 6, 7]) 
In [457]: x[(0,1)]    # same tuple 
Out[457]: array([4, 5, 6, 7]) 
In [458]: x[[0,1]]    # list - index for one dim 
Out[458]: 
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 [459]: x[([0,1],)]   # same 
    ....