numpy索引:不应该拖尾省略号是多余的吗?

时间:2016-12-20 01:40:46

标签: python numpy array-indexing

在尝试正确理解numpy索引规则时,我偶然发现了以下内容。我曾经认为索引中的尾随省略号没有做任何事情。琐事不是吗?除此之外,事实并非如此:

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.
>>> import numpy as np
>>> 
>>> D2 = np.arange(4).reshape((2, 2))
>>>
>>> D2[[1, 0]].shape; D2[[1, 0], ...].shape
(2, 2)
(2, 2)
>>> D2[:, [1, 0]].shape; D2[:, [1, 0], ...].shape
(2, 2)
(2, 2)
>>> # so far so expected; now
... 
>>> D2[[[1, 0]]].shape; D2[[[1, 0]], ...].shape
(2, 2)
(1, 2, 2)
>>> # ouch!
...
>>> D2[:, [[1, 0]]].shape; D2[:, [[1, 0]], ...].shape
(2, 1, 2)
(2, 1, 2)

现在有人知道这是一个错误还是一个功能? 如果是后者,理由是什么?

提前致谢, 保罗

1 个答案:

答案 0 :(得分:5)

显然,[[1, 0]]索引的解释存在一些含糊之处。可能同样的事情在这里讨论:

Advanced slicing when passed list instead of tuple in numpy

我会尝试一个不同的数组,看它是否能让事情变得清晰

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)

使用:...或使索引列表成为一个数组,都将其视为(1,3)索引,并相应地扩展结果的维度

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)

请注意,如果我将转置应用于索引数组,我会得到一个(3,1,2)结果

In [323]: D2[np.array([[1,0,0]]).T,:]
...
In [324]: _.shape
Out[324]: (3, 1, 2)

如果没有:...,则在将[]应用到第一轴之前,它似乎会剥离一层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)

D2[(1,2)]

我认为这里存在向后兼容性问题。我们知道元组层是“冗余的”:D2[1,2]numpy相同。但是,对于早期版本的numeric[])的兼容性,可以以相同的方式处理第一个...图层。

在11月的问题中,我注意到:

  

因此,如果列表不能解释为高级索引列表,那么在顶级列表和元组的处理方式相同。

添加D2[[[0,1]]]是将D2[([0,1],)]@eric/s分开的另一种方式。

来自seburg拉取请求[[1,2]]解释

  

元组规范化是一个相当小的事情(它基本上检查长度为< = np.MAXDIMS的非数组序列,如果它包含另一个序列,slice或None,则将其视为元组)。

([1,2],)是带有列表的1元素列表,因此它被视为元组,即[[1,2]],...DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReferenceFromUrl("my url"); final FirebaseListAdapter<String> firebaseListAdapter = new FirebaseListAdapter<String>(this, String.class, android.R.layout.simple_list_item_1, databaseReference) { @Override protected void populateView(View v, String model, int position) { TextView textView= (TextView) v.findViewById(android.R.id.text1); textView.setText(model); } }; listView.setAdapter(firebaseListAdapter); 已经是一个元组。