为什么numpy混合的基本/高级索引依赖于切片邻接?

时间:2018-12-18 21:41:13

标签: python numpy multidimensional-array numpy-ndarray

我知道之前也曾问过类似的问题(e.g.),但AFAIK没有人回答我的特定问题...

我的问题是关于here中描述的numpy混合高级/基本索引编制:

  

...需要区分两种索引组合情况:

     
      
  • 高级索引由切片,省略号或换轴符分隔。例如x[arr1,:,arr2]
  •   
  • 高级索引彼此相邻。例如x[...,arr1,arr2,:]而不是x[arr1,:,1],因为1在这方面是高级索引。
  •   
     

在第一种情况下,高级索引操作产生的维数首先出现在结果数组中,其后是子空间维数。在第二种情况下,高级索引操作产生的维度将与初始数组中的维度插入到结果数组中的相同位置(后一种逻辑使简单的高级索引表现得像切片一样)。

为什么需要这种区分?

我期望针对情况2所述的行为将在所有情况下使用。索引是否彼此相邻为什么很重要?

我了解您在某些情况下可能需要案例1的行为;例如,索引的“向量化”将沿着新的维度进行。但是这种行为可以应该由用户定义。也就是说,如果案例2的行为是默认行为,则案例1的行为将仅可以使用以下方式实现: x[arr1,:,arr2].reshape((len(arr1),x.shape[1]))

我知道您可以使用np.ix_()实现案例2中描述的行为,但是我认为默认索引行为的这种不一致是意外的和不合理的。有人可以辩解吗?

谢谢

1 个答案:

答案 0 :(得分:2)

案例2的行为案例1的定义不明确。在以下句子中可能会漏掉一个细微之处:

  

在第二种情况下,来自高级索引操作的维将插入到结果数组中,其位置与初始数组中的位置相同

您可能正在想象输入和输出维度之间的一对一对应关系,也许是因为您正在想象Matlab样式的索引。 NumPy不能那样工作。如果您有四个具有以下形状的数组:

    private async Task AskArchyForState()
    {
        var filter = new IntentFilter("com.example.Mehitabel.StateFromArchy");
        var csrc = new TaskCompletionSource<bool>();
        var rcvr = new ActionBroadcastReceiver((context, intent) =>
        {
            State = intent.GetStringExtra("ImportantStateInfo");
            csrc.TrySetResult(State != null);
        });
        RegisterReceiver(rcvr, filter);

        var msg = new Intent("com.example.Archy.SendStateToMehitabel");
        SendBroadcast(msg);

        var task = await Task.WhenAny(csrc.Task, Task.Delay(Timeout));

        UnregisterReceiver(rcvr);
        if (task != csrc.Task)
            bomb("Archy has not answered state query after {0}ms", Timeout);
        if (!csrc.Task.IsCompletedSuccessfully || csrc.Task.Result == false)
            bomb("failed to get all necessary state from Archy");
    }

然后a.shape == (2, 3, 4, 5, 6) b.shape == (20, 30) c.shape == (20, 30) d.shape == (20, 30) 的尺寸为四个,长度分别为3、5、20和30。没有明确的位置放置20和30。NumPy默认将其插入

另一方面,使用a[b, :, c, :, d],则20和30可以到达3、4和5的位置,因为3、4和5彼此相邻。新尺寸的整块会到达原始尺寸的整块的位置,这仅在原始尺寸位于原始形状的单个块中时有效。