2017-10-14 66 views
2

我正在閱讀Python中的Ndarray documentation,它有以下示例。在Python中切分危險的操作?

A 2維數組大小爲2×3的,4個字節的整數的組成 元素:

>>> # The element of x in the *second* row, *third* column, namely, 6. 
>>> x[1, 2] 

>>> x = np.array([[1, 2, 3], [4, 5, 6]], np.int32) 
>>> type(x) 
<type 'numpy.ndarray'> 
>>> x.shape 
(2, 3) 
>>> x.dtype 
dtype('int32') 

陣列可以使用Python容器狀的語法被索引

例如切片可以產生陣列的視圖:

>>> y = x[:,1] 
>>> y 
array([2, 5]) 
>>> y[0] = 9 # this also changes the corresponding element in x 
>>> y 
array([9, 5]) 
>>> x 
array([[1, 9, 3], 
     [4, 5, 6]]) 

我有一個MATLAB背景,當我們做y = x[:, 1]y變得鮮明2×1矩陣,在這之後改變y任何元件產生在原始矩陣x沒有變化。但是,看起來在Python中更改y的元素確實會改變原始數組x

有人可以評論這個操作是否應該避免?因爲我不想通過操作某些數據部分來意外更改我的原始數據。

+2

不要發佈您的代碼的圖片,發佈您的代碼格式的文本 –

+0

您可以使用' 。copy()'as'y = x [:,1] .copy()' – ZdaR

+0

這只是數組視圖,因此視圖中的部分反映在源代碼中。嘗試複製它。 –

回答

1

numpy數組中的切片是對象的視圖(與列表中的切片不同,它將返回一個新對象),這意味着您返回的值是對原始數組的引用。從文章Views versus copies in NumPy引用,重點是我的:

什麼是NumPy數組的視圖?

顧名思義,它只是另一種查看數組數據的方式。從技術上講,這意味着兩個對象的數據是共享的。您可以通過選擇原始數組的切片來創建視圖,也可以通過更改dtype(或兩者的組合)來創建視圖。下面介紹這些不同類型的視圖。

切片視圖

這可能是!NumPy的視圖創作的最常見來源。 用於創建切片視圖的經驗法則是,查看的 元素可以用 原始數組中的偏移量,跨距和計數尋址。例如:

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

當你因爲你想看看數據的一部分或應用上那已經就地完成的操作使用一個片,它是完全安全的。如果您希望修改就地的數據,那麼你要創建的元素的新副本np.copy()

>>> a = np.array([1, 5, 3, 7, 2, 3, 1, 8, 5]) 
>>> b = a[1:5] 
>>> b 
array([5, 3, 7, 2]) 
>>> # this will create a new array and sort it 
>>> np.sort(b) 
array([2, 3, 5, 7]) 
>>> b 
array([5, 3, 7, 2]) 
>>> # this is done in-place, which means it will also affect `a` 
>>> b.sort() 
>>> a 
array([1, 2, 3, 5, 7, 3, 1, 8, 5]) 
1

這絕對是Python的正確行爲。該語言最大的好處之一就是一切都是作爲參考而不是價值來傳遞。如果您確實想從切片創建新的矩陣,請考慮.copy方法。

+3

Python的參數傳遞約定和簡單的賦值語義實際上與切片語義無關。考慮如果'y'是一個普通的舊Python列表(長度爲4,比如說)和'x = y [2:]',那麼修改'x'''不會改變'y'。 OP注意到NumPy數組並非如此。 –