पायथन में "तीन डॉट्स" का क्या मतलब है जब एक नंबर की तरह अनुक्रमण करता है?


87

x[...]नीचे का अर्थ क्या है ?

a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2 * x

1
वह सूची नहीं है।
user2357112


1
यह समझने के लिए मजेदार तरीका है जेम्स पॉवेल की बात youtube.com/watch?v=65_-6kEAq58
SARose

जवाबों:


69

जबकि प्रस्तावित डुप्लिकेट पायथन एलिप्सिस ऑब्जेक्ट क्या करता है? एक सामान्य pythonसंदर्भ में प्रश्न का उत्तर देता है, एक nditerलूप में इसके उपयोग की आवश्यकता है, मुझे लगता है, अतिरिक्त जानकारी।

https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values

पायथन में नियमित रूप से असाइनमेंट केवल स्थान में मौजूदा चर को संशोधित करने के बजाय स्थानीय या वैश्विक चर शब्दकोश में एक संदर्भ बदलता है। इसका मतलब यह है कि केवल x को असाइन करने से एरे के तत्व में वैल्यू नहीं आएगी, बल्कि एक्स को एलीमेंट एलीमेंट के रेफरेंस से बदलकर आपके द्वारा असाइन किए गए वैल्यू के संदर्भ में रखा जाएगा। वास्तव में एरे के तत्व को संशोधित करने के लिए, एक्स को एलिप्सिस के साथ अनुक्रमित किया जाना चाहिए।

उस अनुभाग में आपका कोड उदाहरण शामिल है।

तो मेरे शब्दों में, जगह में x[...] = ...संशोधन x; चर x = ...का लिंक तोड़ दिया होगा nditer, और इसे नहीं बदला। यह पसंद है x[:] = ...लेकिन किसी भी आयाम (0d सहित) के सरणियों के साथ काम करता है। इस संदर्भ xमें यह केवल एक संख्या नहीं है, यह एक सरणी है।

शायद इस nditerपुनरावृत्ति के लिए निकटतम चीज़ , बिना nditerहै:

In [667]: for i, x in np.ndenumerate(a):
     ...:     print(i, x)
     ...:     a[i] = 2 * x
     ...:     
(0, 0) 0
(0, 1) 1
...
(1, 2) 5
In [668]: a
Out[668]: 
array([[ 0,  2,  4],
       [ 6,  8, 10]])

ध्यान दें कि मुझे a[i]सीधे अनुक्रमित और संशोधित करना था । मैं इस्तेमाल नहीं कर सकता था x = 2*x,। इस पुनरावृत्ति xमें एक अदिश राशि है, और इस प्रकार यह परस्पर नहीं है

In [669]: for i,x in np.ndenumerate(a):
     ...:     x[...] = 2 * x
  ...
TypeError: 'numpy.int32' object does not support item assignment

लेकिन nditerमामले xमें एक 0d सरणी है, और परस्पर।

In [671]: for x in np.nditer(a, op_flags=['readwrite']):
     ...:     print(x, type(x), x.shape)
     ...:     x[...] = 2 * x
     ...:     
0 <class 'numpy.ndarray'> ()
4 <class 'numpy.ndarray'> ()
...

और क्योंकि यह 0d है, x[:]इसके बजाय इसका उपयोग नहीं किया जा सकता हैx[...]

----> 3     x[:] = 2 * x
IndexError: too many indices for array

एक सरल सरणी पुनरावृत्ति भी अंतर्दृष्टि दे सकती है:

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

यह पंक्तियों (1 मंद) पर पुनरावृति करता है axतब 1d सरणी होती है, और इसे x[:]=...या तो संशोधित किया जा सकता है x[...]=...

और अगर मैं external_loopअगले खंड से झंडा जोड़ता हूं , xतो अब 1d सरणी है, और x[:] =काम करेगा। लेकिन फिर x[...] =भी काम करता है और अधिक सामान्य है। x[...]अन्य सभी nditerउदाहरणों का उपयोग किया जाता है ।

In [677]: for x in np.nditer(a, op_flags=['readwrite'], flags=['external_loop']):
     ...:     print(x, type(x), x.shape)
     ...:     x[...] = 2 * x
[ 0 16 32 48 64 80] <class 'numpy.ndarray'> (6,)

इस सरल पंक्ति पुनरावृत्ति (2d सरणी पर) की तुलना करें:

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

यह पंक्तियों (1 मंद) पर पुनरावृति करता है axतब 1d सरणी होती है, और इसे x[:] = ...या तो संशोधित किया जा सकता है x[...] = ...

इस nditerपेज को अंत तक सभी तरह से पढ़ें और प्रयोग करें । अपने आप से, nditerयह उपयोगी नहीं है python। यह पुनरावृत्ति को गति नहीं देता है - तब तक नहीं जब तक आप अपना कोड पोर्ट नहीं करते cython। उपयोग np.ndindexकरने वाले कुछ गैर-संकलित numpyकार्यों में से एक है nditer


ध्यान दें कि x [1,:, ...] जैसी चीजें भी एक स्वीकृत वाक्यविन्यास हैं। भविष्य के संदर्भ के लिए छोड़ दिया।
बोर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.