代码之家  ›  专栏  ›  技术社区  ›  SumNeuron

Numpy ndarray:了解切片对象和“:”

  •  0
  • SumNeuron  · 技术社区  · 7 年前

    假设你有:

    data = np.array([ 
            [ 0,   1   ],
            [ 0,   1   ] 
          ], dtype='int64')
    

    打电话

    data[:, 1]
    

    [1. 1.]
    

    然而

    data[(slice(None,None,None), slice(1,2,None))]
    

    产量

    [[1.]
     [1.]]
    

    怎么会?

    如何显式地编写slice对象来获得 [:, 1] ?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Eelco Hoogendoorn    7 年前

    使用切片对象索引与使用整数索引具有不同的语义。使用单个整数进行索引会折叠/删除相应的维度,而使用切片进行索引则不会这样做。

    如果你想用一个整数沿着某个轴建立索引,你可以用一个切片和一些整形逻辑来模拟它;但是最简单的解决方案是用相应的整数替换切片。

    或者,也有np.挤压. 绝对不要在没有axis关键字的情况下使用它,因为这是产生无意行为的代码的保证方法。但是只挤压那些你切割的斧子会产生你想要的效果。

    如果你允许我一个小咆哮:在更高的层次上,我怀疑你所追求的是一个非常numpy反模式。如果我必须制定numpy的第一条规则,那就不是因为轴恰好是单粒子而挤压它们。接受Ndarray并认识到更多的轴不会使代码变得更复杂,但它允许您表达数据的有意义的完整语义。事实上,你在第一个地方切片这个轴表明,这个轴的大小基本上不是1,只是碰巧在一个特定的情况下是这样的。排除单例维度将使任何下游代码几乎不可能以无缺陷的方式编写。如果你必须压缩一个数组,比如说在把它传递给一个绘图函数之前,把它当作C++中的一个栈分配变量对待,并且不要让它的任何引用泄漏到当前的范围内,因为你会混淆该数组的语义,而下游代码不再知道它在看什么。

        2
  •  0
  •   meetaig    7 年前

    似乎你需要在使用一个 slice 对象。或者有一些我不了解的底层实现细节。

    import numpy as np
    data = np.array([
            [ 0,   1   ],
            [ 0,   1   ]
          ], dtype='int64')
    print("desired result")
    print(data[:, 1])
    print("first try")
    print(data[(slice(None,None,None), slice(1,2,None))])
    print("solution")
    print(data[[slice(None,None,None), slice(1,2,None)]].squeeze())
    

    输出:

    desired result
    [1 1]
    first try
    [[1]
     [1]]
    solution
    [1 1]