array-indexing https://www.e-learn.cn/tag/array-indexing zh-hans numpy indexing: shouldn't trailing Ellipsis be redundant? https://www.e-learn.cn/topic/3020137 <span>numpy indexing: shouldn&#039;t trailing Ellipsis be redundant?</span> <span><span lang="" about="/user/205" typeof="schema:Person" property="schema:name" datatype="">耗尽温柔</span></span> <span>2019-12-31 04:56:07</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>While trying to properly understand numpy indexing rules I stumbled across the following. I used to think that a trailing Ellipsis in an index does nothing. Trivial isn't it? Except, it's not actually true:</p> <pre><code>Python 3.5.2 (default, Nov 11 2016, 04:18:53) [GCC 4.8.5] on linux Type "help", "copyright", "credits" or "license" for more information. &gt;&gt;&gt; import numpy as np &gt;&gt;&gt; &gt;&gt;&gt; D2 = np.arange(4).reshape((2, 2)) &gt;&gt;&gt; &gt;&gt;&gt; D2[[1, 0]].shape; D2[[1, 0], ...].shape (2, 2) (2, 2) &gt;&gt;&gt; D2[:, [1, 0]].shape; D2[:, [1, 0], ...].shape (2, 2) (2, 2) &gt;&gt;&gt; # so far so expected; now ... &gt;&gt;&gt; D2[[[1, 0]]].shape; D2[[[1, 0]], ...].shape (2, 2) (1, 2, 2) &gt;&gt;&gt; # ouch! ... &gt;&gt;&gt; D2[:, [[1, 0]]].shape; D2[:, [[1, 0]], ...].shape (2, 1, 2) (2, 1, 2) </code></pre> <p>Now could someone in the know advise me as to whether this is a bug or a feature? And if the latter, what's the rationale?</p> <p>Thanks in advance, Paul</p> <br /><h3>回答1:</h3><br /><p>Evidently there's some ambiguity in the interpretation of the <code>[[1, 0]]</code> index. Possibly the same thing discussed here:</p> <p>Advanced slicing when passed list instead of tuple in numpy</p> <p>I'll try a different array, to see if it makes things any clear</p> <pre><code>In [312]: D2=np.array([[0,0],[1,1],[2,2]]) In [313]: D2 Out[313]: array([[0, 0], [1, 1], [2, 2]]) In [316]: D2[[[1,0,0]]] Out[316]: array([[1, 1], [0, 0], [0, 0]]) In [317]: _.shape Out[317]: (3, 2) </code></pre> <p>Use of <code>:</code> or <code>...</code> or making the index list an array, all treat it as a (1,3) index, and expand the dimensions of the result accordingly</p> <pre><code>In [318]: D2[[[1,0,0]],:] Out[318]: array([[[1, 1], [0, 0], [0, 0]]]) In [319]: _.shape Out[319]: (1, 3, 2) In [320]: D2[np.array([[1,0,0]])] Out[320]: array([[[1, 1], [0, 0], [0, 0]]]) In [321]: _.shape Out[321]: (1, 3, 2) </code></pre> <p>Note that if I apply transpose to the indexing array I get a (3,1,2) result</p> <pre><code>In [323]: D2[np.array([[1,0,0]]).T,:] ... In [324]: _.shape Out[324]: (3, 1, 2) </code></pre> <p>Without <code>:</code> or <code>...</code>, it appears to strip off one layer of <code>[]</code> before applying it to the 1st axis: </p> <pre><code>In [330]: D2[[1,0,0]].shape Out[330]: (3, 2) In [331]: D2[[[1,0,0]]].shape Out[331]: (3, 2) In [333]: D2[[[[1,0,0]]]].shape Out[333]: (1, 3, 2) In [334]: D2[[[[[1,0,0]]]]].shape Out[334]: (1, 1, 3, 2) In [335]: D2[np.array([[[[1,0,0]]]])].shape Out[335]: (1, 1, 1, 3, 2) </code></pre> <p>I think there's a backward compatibility issue here. We know that the tuple layer is 'redundant': <code>D2[(1,2)]</code> is the same as <code>D2[1,2]</code>. But for compatibility for early versions of <code>numpy</code> (<code>numeric</code>) that first <code>[]</code> layer may be treated in the same way. </p> <p>In that November question, I noted:</p> <blockquote> <p>So at a top level a list and tuple are treated the same - if the list can't interpreted as an advanced indexing list.</p> </blockquote> <p>The addition of a <code>...</code> is another way of separating the <code>D2[[[0,1]]]</code> from <code>D2[([0,1],)]</code>.</p> <p>From <code>@eric/s</code> pull request <code>seburg</code> explains</p> <blockquote> <p> The tuple normalization is a rather small thing (it basically checks for a non-array sequence of length &lt;= np.MAXDIMS, and if it contains another sequence, slice or None consider it a tuple).</p> </blockquote> <p><code>[[1,2]]</code> is a 1 element list with a list, so it is considered a tuple, i.e. <code>([1,2],)</code>. <code>[[1,2]],...</code> is a tuple already.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/41233678/numpy-indexing-shouldnt-trailing-ellipsis-be-redundant</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/python" hreflang="zh-hans">python</a></div> <div class="field--item"><a href="/tag/numpy" hreflang="zh-hans">numpy</a></div> <div class="field--item"><a href="/tag/array-indexing" hreflang="zh-hans">array-indexing</a></div> </div> </div> Mon, 30 Dec 2019 20:56:07 +0000 耗尽温柔 3020137 at https://www.e-learn.cn Using python range objects to index into numpy arrays https://www.e-learn.cn/topic/2402807 <span>Using python range objects to index into numpy arrays</span> <span><span lang="" about="/user/224" typeof="schema:Person" property="schema:name" datatype="">前提是你</span></span> <span>2019-12-12 18:16:43</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I've seen it once or twice before, but I can't seem to find any official docs on it: Using python <code>range</code> objects as indices in numpy.</p> <pre><code>import numpy as np a = np.arange(9).reshape(3,3) a[range(3), range(2,-1,-1)] # array([2, 4, 6]) </code></pre> <p>Let's trigger an index error just to confirm that ranges are not in the official range (pun intended) of legal indexing methods:</p> <pre><code>a['x'] # Traceback (most recent call last): # File "&lt;stdin&gt;", line 1, in &lt;module&gt; # IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices </code></pre> <p>Now, a slight divergence between numpy and its docs is not entirely unheard of and does not necessarily indicate that a feature is not intended (see for example here).</p> <p>So, does anybody know why this works at all? And if it is an intended feature what are the exact semantics / what is it good for? And are there any ND generalizations?</p> <br /><h3>回答1:</h3><br /><p><em>Not a proper answer, but too long for comment.</em></p> <p>In fact, it seems to work with about any indexable object:</p> <pre><code>import numpy as np class MyIndex: def __init__(self, n): self.n = n def __getitem__(self, i): if i &lt; 0 or i &gt;= self.n: raise IndexError return i def __len__(self): return self.n a = np.array([1, 2, 3]) print(a[MyIndex(2)]) # [1 2] </code></pre> <p>I <em>think</em> the relevant lines in NumPy's code are below this comment in core/src/multiarray/mapping.c:</p> <pre class="lang-c prettyprint-override"><code>/* * Some other type of short sequence - assume we should unpack it like a * tuple, and then decide whether that was actually necessary. */ </code></pre> <p>But I'm not entirely sure. For some reason, this hangs if you remove the <code>if i &lt; 0 or i &gt;= self.n: raise IndexError</code>, even though there is a <code>__len__</code>, so at some point it seems to be iterating through the given object until <code>IndexError</code> is raised.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>Just to wrap this up (thanks to @WarrenWeckesser in the comments): This behavior is actually documented. One only has to realize that <code>range</code> objects are python sequences in the strict sense.</p> <p>So this is just a case of fancy indexing. Be warned, though, that it is very slow:</p> <pre><code>&gt;&gt;&gt; a = np.arange(100000) &gt;&gt;&gt; timeit(lambda: a[range(100000)], number=1000) 12.969507368048653 &gt;&gt;&gt; timeit(lambda: a[list(range(100000))], number=1000) 7.990526253008284 &gt;&gt;&gt; timeit(lambda: a[np.arange(100000)], number=1000) 0.22483703796751797 </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/53123009/using-python-range-objects-to-index-into-numpy-arrays</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/python" hreflang="zh-hans">python</a></div> <div class="field--item"><a href="/tag/numpy" hreflang="zh-hans">numpy</a></div> <div class="field--item"><a href="/tag/array-indexing" hreflang="zh-hans">array-indexing</a></div> </div> </div> Thu, 12 Dec 2019 10:16:43 +0000 前提是你 2402807 at https://www.e-learn.cn numpy indexing: shouldn't trailing Ellipsis be redundant? https://www.e-learn.cn/topic/1051856 <span>numpy indexing: shouldn&#039;t trailing Ellipsis be redundant?</span> <span><span lang="" about="/user/62" typeof="schema:Person" property="schema:name" datatype="">喜夏-厌秋</span></span> <span>2019-12-02 06:23:21</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><div class="alert alert-danger" role="alert"> <p>While trying to properly understand numpy indexing rules I stumbled across the following. I used to think that a trailing Ellipsis in an index does nothing. Trivial isn't it? Except, it's not actually true:</p> <pre><code>Python 3.5.2 (default, Nov 11 2016, 04:18:53) [GCC 4.8.5] on linux Type "help", "copyright", "credits" or "license" for more information. &gt;&gt;&gt; import numpy as np &gt;&gt;&gt; &gt;&gt;&gt; D2 = np.arange(4).reshape((2, 2)) &gt;&gt;&gt; &gt;&gt;&gt; D2[[1, 0]].shape; D2[[1, 0], ...].shape (2, 2) (2, 2) &gt;&gt;&gt; D2[:, [1, 0]].shape; D2[:, [1, 0], ...].shape (2, 2) (2, 2) &gt;&gt;&gt; # so far so expected; now ... &gt;&gt;&gt; D2[[[1, 0]]].shape; D2[[[1, 0]], ...].shape (2, 2) (1, 2, 2) &gt;&gt;&gt; # ouch! ... &gt;&gt;&gt; D2[:, [[1, 0]]].shape; D2[:, [[1, 0]], ...].shape (2, 1, 2) (2, 1, 2) </code></pre> <p>Now could someone in the know advise me as to whether this is a bug or a feature? And if the latter, what's the rationale?</p> <p>Thanks in advance, Paul</p> </div><div class="panel panel-info"><div class="panel-heading">hpaulj</div><div class="panel-body"> <p>Evidently there's some ambiguity in the interpretation of the <code>[[1, 0]]</code> index. Possibly the same thing discussed here:</p> <p><a href="https://stackoverflow.com/questions/40598824/advanced-slicing-when-passed-list-instead-of-tuple-in-numpy" rel="nofollow">Advanced slicing when passed list instead of tuple in numpy</a></p> <p>I'll try a different array, to see if it makes things any clear</p> <pre><code>In [312]: D2=np.array([[0,0],[1,1],[2,2]]) In [313]: D2 Out[313]: array([[0, 0], [1, 1], [2, 2]]) In [316]: D2[[[1,0,0]]] Out[316]: array([[1, 1], [0, 0], [0, 0]]) In [317]: _.shape Out[317]: (3, 2) </code></pre> <p>Use of <code>:</code> or <code>...</code> or making the index list an array, all treat it as a (1,3) index, and expand the dimensions of the result accordingly</p> <pre><code>In [318]: D2[[[1,0,0]],:] Out[318]: array([[[1, 1], [0, 0], [0, 0]]]) In [319]: _.shape Out[319]: (1, 3, 2) In [320]: D2[np.array([[1,0,0]])] Out[320]: array([[[1, 1], [0, 0], [0, 0]]]) In [321]: _.shape Out[321]: (1, 3, 2) </code></pre> <p>Note that if I apply transpose to the indexing array I get a (3,1,2) result</p> <pre><code>In [323]: D2[np.array([[1,0,0]]).T,:] ... In [324]: _.shape Out[324]: (3, 1, 2) </code></pre> <p>Without <code>:</code> or <code>...</code>, it appears to strip off one layer of <code>[]</code> before applying it to the 1st axis: </p> <pre><code>In [330]: D2[[1,0,0]].shape Out[330]: (3, 2) In [331]: D2[[[1,0,0]]].shape Out[331]: (3, 2) In [333]: D2[[[[1,0,0]]]].shape Out[333]: (1, 3, 2) In [334]: D2[[[[[1,0,0]]]]].shape Out[334]: (1, 1, 3, 2) In [335]: D2[np.array([[[[1,0,0]]]])].shape Out[335]: (1, 1, 1, 3, 2) </code></pre> <p>I think there's a backward compatibility issue here. We know that the tuple layer is 'redundant': <code>D2[(1,2)]</code> is the same as <code>D2[1,2]</code>. But for compatibility for early versions of <code>numpy</code> (<code>numeric</code>) that first <code>[]</code> layer may be treated in the same way. </p> <p>In that November question, I noted:</p> <blockquote> <p>So at a top level a list and tuple are treated the same - if the list can't interpreted as an advanced indexing list.</p> </blockquote> <p>The addition of a <code>...</code> is another way of separating the <code>D2[[[0,1]]]</code> from <code>D2[([0,1],)]</code>.</p> <p>From <code>@eric/s</code> pull request <code>seburg</code> explains</p> <blockquote> <p> The tuple normalization is a rather small thing (it basically checks for a non-array sequence of length &lt;= np.MAXDIMS, and if it contains another sequence, slice or None consider it a tuple).</p> </blockquote> <p><code>[[1,2]]</code> is a 1 element list with a list, so it is considered a tuple, i.e. <code>([1,2],)</code>. <code>[[1,2]],...</code> is a tuple already.</p> </div></div><div class="alert alert-warning" role="alert"><p>来源:<code>https://stackoverflow.com/questions/41233678/numpy-indexing-shouldnt-trailing-ellipsis-be-redundant</code></p></div></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/python" hreflang="zh-hans">python</a></div> <div class="field--item"><a href="/tag/numpy" hreflang="zh-hans">numpy</a></div> <div class="field--item"><a href="/tag/array-indexing" hreflang="zh-hans">array-indexing</a></div> </div> </div> Sun, 01 Dec 2019 22:23:21 +0000 喜夏-厌秋 1051856 at https://www.e-learn.cn Do pointers support “array style indexing”? https://www.e-learn.cn/topic/229986 <span>Do pointers support “array style indexing”?</span> <span><span lang="" about="/user/62" typeof="schema:Person" property="schema:name" datatype="">喜夏-厌秋</span></span> <span>2019-11-27 03:40:56</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p><em>(Self-answered Q&amp;A - this matter keeps popping up)</em></p> <p>I assume that the reader is aware of how pointer arithmetic works.</p> <pre><code>int arr[3] = {1,2,3}; int* ptr = arr; ... *(ptr + i) = value; </code></pre> <p>Teachers/C books keep telling me I shouldn't use <code>*(ptr + i)</code> like in the above example, because "pointers support array style indexing" and I should be using <code>ptr[i] = value;</code> instead. No argument there - much easier to read.</p> <p>But looking through the C standard, I find nothing called "array style indexing". In fact, the operator <code>[]</code> is not expecting the either operand to be an array, but instead a pointer or an integer!</p> <blockquote> <p><strong>6.5.2.1 Array subscripting</strong></p> <p><strong>Constraints</strong></p> <p>One of the expressions shall have type ‘‘pointer to complete object <em>type</em>’’, the other expression shall have integer type, and the result has type ‘‘<em>type</em>’’.</p> </blockquote> <p>Why does the <em>array</em> subscripting operator not expect an array? Is the standard wrong? Is my teacher/C book confused?</p> <br /><h3>回答1:</h3><br /><p>You should indeed be using <code>ptr[i]</code> over <code>*(ptr + i)</code> for readability reasons. But apart from that, the <code>[]</code> operator is, strictly speaking, actually never used with an array operand.</p> <p>Arrays, when used in an expression, always "decay" into a pointer to the first element (with some exceptions). C17 6.3.2.1/3, emphasis mine:</p> <blockquote> <p>Except when it is the operand of the sizeof operator, or the unary &amp; operator, or is a string literal used to initialize an array, <strong>an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object</strong> and is not an lvalue.</p> </blockquote> <p>Meaning that whenever you type <code>arr[i]</code>, the operand <code>arr</code> gets replaced by a pointer to the first element inside that array. This is informally referred to as "array decaying". More info here: What is array decaying?</p> <p>So whenever you use the <code>[]</code> operator, you use it on a pointer. Always. </p> <p>The C standard says that this operator is guaranteed to be equivalent to the pointer arithmetic (C17 6.5.2.1/2):</p> <blockquote> <p>The definition of the subscript operator <code>[]</code> is that <code>E1[E2]</code> is identical to <code>(*((E1)+(E2)))</code>.</p> </blockquote> <p>So whenever we type <code>arr[i]</code>, it actually gets silently replaced by <code>*(arr+i)</code>. Where <code>arr</code> is still a pointer to the first element.</p> <p>And this is why the description you quoted tells you that <em>either</em> operand could be a pointer and the other an integer. Because obviously it doesn't matter if we type <code>*(arr+i)</code> or <code>*(i+arr)</code> - that's equivalent code. </p> <p>Which in turn allows us to write obfuscated "joke" code like <code>i[arr]</code>, which is actually valid C and fully equivalent to <code>arr[i]</code>. But don't write such code in real applications.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/55747822/do-pointers-support-array-style-indexing</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-1" hreflang="zh-hans">c</a></div> <div class="field--item"><a href="/tag/arrays" hreflang="zh-hans">arrays</a></div> <div class="field--item"><a href="/tag/pointer-arithmetic" hreflang="zh-hans">pointer-arithmetic</a></div> <div class="field--item"><a href="/tag/subscript-operator" hreflang="zh-hans">subscript-operator</a></div> <div class="field--item"><a href="/tag/array-indexing" hreflang="zh-hans">array-indexing</a></div> </div> </div> Tue, 26 Nov 2019 19:40:56 +0000 喜夏-厌秋 229986 at https://www.e-learn.cn