2013-02-04 38 views
8

मैं बस की खोज की - संयोग से - कि numpy में एक सरणी एक खाली टपल द्वारा अनुक्रमित किया जा सकता है:numpy में, खाली tuple बनाम ellipsis के साथ एक सरणी अनुक्रमणित क्या करता है?

In [62]: a = arange(5) 

In [63]: a[()] 
Out[63]: array([0, 1, 2, 3, 4]) 

मैं numpy wiki ZeroRankArray पर कुछ प्रलेखन पाया:

(साशा) पहले, जो कुछ भी पसंद एक्स [...] और एक्स [()] के लिए बनाया गया है क्योंकि वे वही होना चाहिए क्योंकि ... "जितना आवश्यक हो उतना आवश्यक" के लिए सिंटैक्टिक चीनी है, जो शून्य रैंक के मामले में होता है ... = (:,) * 0 =()। दूसरा, रैंक शून्य सरणी और numpy scalar प्रकार numpy के भीतर अंतर-परिवर्तनीय हैं, लेकिन कुछ पाइथन संरचनाओं में numpy scalars का उपयोग किया जा सकता है जहां ndarrays नहीं कर सकते हैं।

तो, 0-डी सरणियों a[()] और a[...] के लिए बराबर होना चाहिए रहे हैं। क्या वे उच्च-आयामी सरणी भी हैं? वे दृढ़ता से प्रतीत होते हैं:

In [65]: a = arange(25).reshape(5, 5) 

In [66]: a[()] is a[...] 
Out[66]: False 

In [67]: (a[()] == a[...]).all() 
Out[67]: True 

In [68]: a = arange(3**7).reshape((3,)*7) 

In [69]: (a[()] == a[...]).all() 
Out[69]: True 

लेकिन, यह नहीं वाक्यात्मक चीनी है।

In [76]: a[()] is a 
Out[76]: False 

In [77]: a[...] is a 
Out[77]: True 

In [79]: b = array(0) 

In [80]: b[()] is b 
Out[80]: False 

In [81]: b[...] is b 
Out[81]: True 

और फिर वहाँ एक खाली सूची, जो कुछ और पूरी तरह से करता है द्वारा अनुक्रमण के मामले है, लेकिन के बराबर प्रकट होता है: एक उच्च आयामी सरणी के लिए, और नहीं भी 0-डी सरणी के लिए नहीं एक खाली ndarray साथ अनुक्रमण:

In [78]: a[[]] 
Out[78]: array([], shape=(0, 3, 3, 3, 3, 3, 3), dtype=int64) 

In [86]: a[arange(0)] 
Out[86]: array([], shape=(0, 3, 3, 3, 3, 3, 3), dtype=int64) 

In [82]: b[[]] 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 

IndexError: 0-d arrays can't be indexed. 

तो, ऐसा लगता है कि () और ... समान है, लेकिन काफी समान नहीं और अनुक्रमण हैं [] कुछ और मतलब है के साथ पूरी तरह। और a[] या b[]SyntaxError एस हैं। सूचियों के साथ अनुक्रमण index arrays पर दस्तावेज किया गया है, और tuples at the end of the same document के साथ अनुक्रमण के बारे में एक छोटी सूचना है।

सवाल छोड़ कि:

a[()] और a[...] डिजाइन द्वारा के बीच का अंतर है? फिर डिजाइन क्या है?

(प्रश्न के किसी भी तरह याद ताजा: What does the empty `()` do on a Matlab matrix?)

संपादित करें:

वास्तव में, यहां तक ​​कि scalars एक खाली टपल द्वारा अनुक्रमित किया जा सकता है:

In [36]: numpy.int64(10)[()] 
Out[36]: 10 

उत्तर

6

A[...] के उपचार के एक विशेष मामला, always return A itself करने के लिए अनुकूलित है:

if (op == Py_Ellipsis) { 
    Py_INCREF(self); 
    return (PyObject *)self; 
} 

कुछ भी बाकी है कि बराबर जैसे होना चाहिए

>>> A[()] is A 
False 
>>> A[()].base is A 
True 

यह एक अनावश्यक और समय से पहले अनुकूलन लगता है, A[(Ellipsis,)] और A[()] हमेशा की तरह ही परिणाम प्राप्त होगा: A[:], A[(Ellipsis,)], A[()], A[(slice(None),) * A.ndim] बजाय एक A की सम्पूर्णता के जिसका baseA है देखने के लिए, वापस आ जाएगी (A पर एक संपूर्ण दृश्य)। https://github.com/numpy/numpy/commit/fa547b80f7035da85f66f9cbabc4ff75969d23cd को देखकर ऐसा लगता है कि यह मूल रूप से आवश्यक था क्योंकि ... के साथ अनुक्रमण 0 डी सरणी पर ठीक से काम नहीं करता था (पहले https://github.com/numpy/numpy/commit/4156b241aa3670f923428d4e72577a9962cdf042 यह तत्व को स्केलर के रूप में वापस कर देगा), फिर स्थिरता के लिए सभी सरणी तक बढ़ाया गया; तब से, इंडेक्सिंग को 0 डी सरणी पर तय किया गया है, इसलिए ऑप्टिमाइज़ेशन की आवश्यकता नहीं है, लेकिन यह आसपास के आसपास चिपकने में कामयाब रहा है (और शायद कुछ कोड है जो A[...] is A पर सत्य है)।

+0

'ए [(:,) * एन्डिम्स] 'पाइथन 3.2, numpy 1.6.2 पर' सिंटेक्स त्रुटि 'फेंकता है। मुझे लगता है कि यह अधिक बोझिल होना चाहिए 'ए [(टुकड़ा (कोई नहीं),) * एन्डिम] '(भी, यह' एन्डिम 'है, न कि' एन्डिम्स ')। – gerrit

+0

@gerrit धन्यवाद, तय। – ecatmur

4

जबकि उदाहरण में आपने दिया है, खाली ट्यूपल और इलिप्सिस एक समान परिणाम देते हैं, आम तौर पर वे विभिन्न उद्देश्यों की पूर्ति करते हैं। एक सरणी अनुक्रमणित करते समय, A[i, j, k] == A[(i, j, k)] और विशेष रूप से A[...] == A[(Ellipsis,)]। यहां टुपल इंडेक्सिंग तत्वों के लिए बस एक कंटेनर के रूप में कार्य करता है।

index = (0,) * A.ndim 
A[index] 

सूचना है कि क्योंकि टपल अनुक्रमण तत्वों के लिए कंटेनर है, यह अन्य सूचकांकों के साथ संयुक्त नहीं किया जा सकता, उदाहरण के लिए: जब आप एक चर के रूप में सूचकांक में हेरफेर करने, उदाहरण के लिए आप कर सकते हैं की जरूरत है यह उपयोगी हो सकता A[(), 0] == A[[], 0] और A[(), 0] != A[..., 0]

एक सरणी A एक खाली टपल साथ का अनुक्रमण A.ndim की तुलना में कम सूचकांक के साथ अनुक्रमित किया जा सकता क्योंकि, उस व्यवहार का एक स्वाभाविक विस्तार है और यह कुछ स्थितियों में उपयोगी हो सकता है, उदाहरण के लिए ऊपर दिए गए कोड snipit काम करेंगे जब A.ndim == 0

संक्षेप में, ट्यूपल इंडेक्सिंग तत्वों के लिए एक कंटेनर के रूप में कार्य करता है, जिसे खाली होने की अनुमति है, जबकि इलिप्सिस संभावित अनुक्रमण तत्वों में से एक है।

संबंधित मुद्दे