標籤:

Numpy中arr[:]和arr[...],arr[:,i,j] 與arr[:][i][j]的區別?

arr[:]和arr[...]是一樣的嗎?那為什麼numpy中多一個arr[...]?

arr[:,i,j] 與arr[:][i][j]這兩種寫法又有什麼區別呢?


唔,謝邀

先答最後一問吧,前兩問略超我的能力範圍……

arr[:,i,j] 與 arr[:][i][j] 這兩種寫法,額,是完全不一樣的……舉個小栗子:

不知題主懂沒有?(σ"ω")σ

回到第一問;首先是 arr[...] 這種用法我幾乎沒見過……不過單從我剛剛測試的幾組結果來看,它和 arr[:] 的用法大概是一樣的、而且微妙地比 arr[:] 要快一點

(經題主指正,這個觀點是錯誤的;事實上,「...」是多個連續「:」的一種性能頗高的替代;栗子可參見最後)

舉個小栗子:

(這其實挺毀三觀的……虧我之前一直用的都是「:」……結果「..."貌似更好……)

此外需要指出的是,arr[:] 和 arr[...] 都不是淺拷貝!!!

事實上,它們返回的都是視圖;換句話說,我認為如下兩個表達式是等價的:

x = y[:]
x = y

其中 y 是一個 Numpy 數組

再看第二問,綜合我上面的回答,我只能大膽地(瞎 jb)(喂)猜測:

  • 保留 「:」 是因為 Python 裡面有 「:」 的用法,可能比較好接受一點
  • 「...」 是 Numpy 自己弄的一個更契合 Numpy 數組的方法、所以它的表現可能更好一點

鑒於我對這部分知識也不太了解,恕不能從原理的角度去解釋了……期待有大神能夠指教一下 (σ"ω")σ

【在題主的指正下、補充幾組「:」和「...」的栗子】

這說明做切片時、最好只用一個「...」(雖然用多個也是可以的、但性能會變差),且一個「...」可以替換多個連續的「:」、且替換後的性能更好。以及似乎替換掉的連續的「:」越多、替換後的性能提升越大:

接下來看另一個栗子:

當做切片時的「:」不連續出現時,用「...」替換其中一個「:」似乎也能微妙地提升性能以上


一、這裡的arr[:]和arr[...]可以認為是一樣的。但是省略號(Ellipsis)... 在numpy里的indexing表示一個或多個冒號( :) 號。文檔里這樣說:

Ellipsis expand to the number of : objects needed to make a selection tuple of the same length as x.ndim. There may only be a single ellipsis present.

這個省略號語法上比寫多個冒號方便。關於Ellipsis,需要關心的問題可能是返回結果到底是copy還是view:實際上在numpy里,basic indexing總是返回view:

All arrays generated by basic slicing are always views of the original array.

而advanced indexing總是返回一個copy:

Advanced indexing always returns a copy of the data.

而單獨的[...]是basic indexing的方法之一。

當然,混合basic和advanced的indexing也可以,至於具體細節,可以參考 Indexing - NumPy v1.12 Manual。

二、arr[:,i,j] 與arr[:][i][j]是不一樣的。

arr[:][i][j]其實是:

tmp = arr[:]
tmp = tmp[i]
tmp[j]

由於tmp=arr[:] 什麼都沒做,所以其實arr[:][i][j]等價的是 arr[i,j,:],而不是arr[:,i,j]。


標記一下 晚點答


推薦閱讀:

為什麼numpy的array那麼快?
求較好的numpy scipy 資料推薦?

TAG:Python | numpy |