2013-02-21 57 views
4

我主要使用numpy進行數據分析,不太瞭解底層程序,所以這可能是顯而易見的。設置屬性和調用就地變異方法之間的區別?

我不明白設置一個屬性,通過簡單地分配它與調用一個方法,就地改變該屬性之間的差異。在這裏你都可以做的例子是:

In [1]: import numpy as np 

In [2]: a = np.array([[1, 2, 3], 
    ...:    [4, 5, 6]]) 

In [3]: a.shape 
Out[3]: (2, 3) 

In [4]: a.reshape(3,2) 
Out[4]: 
array([[1, 2], 
     [3, 4], 
     [5, 6]]) 

In [5]: a 
Out[5]: 
array([[1, 2, 3], 
     [4, 5, 6]]) 

In [6]: a.resize(3,2) 

In [7]: a 
Out[7]: 
array([[1, 2], 
     [3, 4], 
     [5, 6]]) 

In [8]: a.shape = (6,) 

In [9]: a 
Out[9]: array([1, 2, 3, 4, 5, 6]) 

In [10]: a.__setattr__('shape',(3,2)) 

In [11]: a 
Out[11]: 
array([[1, 2], 
     [3, 4], 
     [5, 6]]) 

我不明白有什麼區別投入68之間。顯然,兩者都改變​​了a.shape屬性,而不是像4那樣返回重構對象。他們都只需撥打a.__setattr__(),如10?如果是這樣,爲什麼他們都存在?

(我知道a.resize()有額外的能力來增加或減少分配的內存,但我沒有使用,在這裏---這是否口是心非只與方法存在增加了一些其他身份?)

+0

看看源代碼:http://github.com/numpy/numpy/blob/v1.7.0/numpy/core/fromnumeric.py#L108 – Blender 2013-02-21 01:05:27

+0

我想我實際上需要'def resize'這一行: https://github.com/numpy/numpy/blob/v1.7.0/numpy/core/fromnumeric.py#L817 – askewchan 2013-02-21 01:07:18

+0

這兩個來源都是用於獨立'numpy'函數的,它們的行爲完全可以理解。這是我不明白的方法與設置屬性。它可能隱藏在[''c源代碼](https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/shape.c),但我不知道如何將'c'代碼翻譯成'class'屬性如何改變。 – askewchan 2013-02-21 02:25:38

回答

1

我讀過你的問題現在幾次,覺得我可以解決一切:

a.reshape(3,2) 
# returns a new array 

a.resize(3,2) 
# returns None, operates on the same array 
# (equivalent to modifying ndarray.shape here since no. of elements is unchanged) 

a.shape = (6,) 
# operates on the same array, uses property trick to hide detailed 
# setter logic behind normal attribute access. 
# note the parens are unnecessary here - equivalent is a.shape = 6, 
# NOT equivalent to a = a.reshape(6,), which would change the id(a) 

a.__setattr__('shape',(3,2)) 
# just an ugly way of doing a.shape = 3,2 

你的主要問題似乎是關於方法的非唯一性來改變數組的形狀。

顯然既改變代替a.shape屬性,而不是返回重構對象作爲4

是。或者更準確地說,兩者都改變​​了陣列(並且結果修改由shape「屬性」返回的值)。

他們都只打電話a.__setattr__()在10?

他們不是絕對必須致電a.__setattr__(...)。他們可以改變一些內部的self._shape變量,它仍然可以改變a.shape返回的內容。

通過創建自己的課程,您可以看到誰實際使用__setattr__。:

class my_ndarray(np.ndarray): 
    def __setattr__(self, name, value): 
     print '__setattr__ called with name={}, value={}'.format(name, value) 
     super(my_ndarray, self).__setattr__(name, value) 

a_ = my_ndarray(a.shape) 
a_[:] = a 

在這種情況下,答案是,無論是a_.resize也不a_.reshape使用__setattr__

如果是這樣,爲什麼它們都存在?

resize可以做的比當元素的數量是不同的重塑這麼多的事實是有足夠的理由對我來說。當你需要做的只是重塑時,使用調整大小會很奇怪,但爲什麼應該numpy(應該是高性能的)麻煩警告你或者人爲地限制你在「可以」重新使用時調整大小代替?

如果您擔心蟒蛇#13,numpy禪宗的明顯違反,並不是尋找一致性的最佳地點。例如,比較np.eyenp.identity!什麼是numpythonic並不總是pythonic。

2

8中的例子實際上叫做property,python讓你可以在版本2.1+中使用。

例如

@property 
def shape(self): 
    """I'm the 'shape' property.""" 
    return self._shape 

@shape.setter 
def shape(self, value): 
    self._shape = value 

__setattr__調用setter

x.__setattr__('shape', value) 

相當於(在屬性setter上面看)。

x.shape = value 

底層邏輯總是調用修飾符函數。

+0

很感謝!所以如果'shape.setter'屬性被創建,爲什麼還要有另一種方法'resize'? – askewchan 2013-02-25 18:51:26

+0

@askewchan你應該問這個問題編寫模塊的人。我不熟悉numpy對不起:( – 2013-02-25 19:00:33

+0

@askewchan np.ndarray.resize是一個不同的東西,它重新分配數據區的空間,如果有必要。reshape用於相同數量的元素,但np.ndarray.resize和np .resize沒有這個限制 – wim 2013-02-27 01:17:10

相關問題