numpy中array數組對象的儲存方式(n,1)和(n,)的區別


  資料:https://stackoverflow.com/questions/22053050/difference-between-numpy-array-shape-r-1-and-r

  這篇文章是我偶然點開的stackoverflow上的一個問題,是關於numpy中的array對象的。numpy在python、機器學習界的重要地位不用多說了吧。在此把這個回答翻譯領悟一下,以供學習。

  注:僅為學習目的翻譯,作者是Gareth Rees,可能會有我自己的修改。

  For learning purposes only !!!

  看待NumPy arrays的最好方式是把它分為兩個部分,一個數據緩沖區包含了一塊raw elements(原始元素),以及一個view(我叫它視窗)來描述解釋數據緩沖區。

  例如如果我們創建一個包含12個整型數的數組 a 

>>> a = numpy.arange(12)
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

  則 a 包含了一個數據緩沖區,儲存成如下的樣子:

┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘

  以及一個視窗,定義了怎樣解釋數據:

>>> a.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>> a.dtype
dtype('int64')
>>> a.itemsize
8
>>> a.strides
(8,)
>>> a.shape
(12,)

  在這里,shape=(12,)意味着這個數組僅僅被一個索引支配:從0到11。從概念上講,假如我們使用這個單獨的索引給 打上標簽,那么 a 將看起來像這樣:

i= 0    1    2    3    4    5    6    7    8    9   10   11
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘

  reshape一個數組的操作不會改變數據緩沖區,而是創建一個新的解釋數據的視窗。

>>> b = a.reshape((3, 4))

  上面的操作創建了一個和 擁有同一個數據緩沖區的 ,但是現在它被兩個索引所支配(two-dimensions indexed)。一個從0到2,一個從0到3,假如我們給數據打上標簽,b 看起來會像這樣:

i= 0    0    0    0    1    1    1    1    2    2    2    2
j= 0    1    2    3    0    1    2    3    0    1    2    3
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘

  這也意味着:

>>> b[2,1]
9

  第二個索引比第一個索引變化的快,假如想反過來,可以使用下面的參數創造一個數組 c 

>>> c = a.reshape((3, 4), order='F')

  補充:order='F'或者order='C'表示數組的索引方式分別像C語言或者Fortran,'C'是缺省值

  這樣會產生一個有如下索引的數組:

i= 0    1    2    0    1    2    0    1    2    0    1    2
j= 0    0    0    1    1    1    2    2    2    3    3    3
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘

  意味着

>>> c[2,1]
5

  有了前面的鋪墊,就很容易理解下面一個例子了:

>>> d = a.reshape((12, 1))

  數組被兩個索引支配,第一個索引從0到11,第二個索引始終為0:

i= 0    1    2    3    4    5    6    7    8    9   10   11
j= 0    0    0    0    0    0    0    0    0    0    0    0
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘

  所以:

>>> d[10,0]
10

  一個展平的一維數組從某種意義上來說是自由的,所以我們完全可以自己定義每一維的大小:

>>> e = a.reshape((1, 2, 1, 6, 1))

  上面的操作創建了一個這樣的數組:

i= 0    0    0    0    0    0    0    0    0    0    0    0
j= 0    0    0    0    0    0    1    1    1    1    1    1
k= 0    0    0    0    0    0    0    0    0    0    0    0
l= 0    1    2    3    4    5    0    1    2    3    4    5
m= 0    0    0    0    0    0    0    0    0    0    0    0
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘

  所以:

>>> e[0,1,0,0,0]
6


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM