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

时间:2018-08-28 08:43:01

标签: python python-3.x numpy numpy-ndarray

假设您有:

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 个答案:

答案 0 :(得分:1)

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

如果您希望具有沿某个轴使用单个整数进行索引的行为,则可以使用切片和一些重塑逻辑对其进行仿真;但是最不费力的解决方案是只用相应的整数替换该切片。

或者,有np.squeeze。绝对不要在没有axis关键字的情况下使用它,因为这是产生意外行为的代码的保证配方。但是,仅挤压您切过的那些轴会产生您似乎想要的效果。

如果您可以允许我做一个小蚁,从更高的角度来看,我怀疑您追求的是一个非常麻木的反模式。如果我必须制定numpy的第一个规则,那不是因为轴碰巧是单例而挤压轴。拥抱ndarray并意识到更多的轴不会使您的代码更复杂,但是它使您可以表达数据的有意义的语义。首先要对该轴进行切片的事实表明,该轴的大小基本上不是1;相反,在特定情况下恰好是如此。压缩该单例维度将几乎不可能以numpythonic和无错误的方式编写任何下游代码。如果您绝对必须压缩数组,例如在将其传递给绘图函数之前说,请像对待C ++中那样为堆栈分配的变量那样对待它,并且不要让对其的任何引用泄漏到当前范围之外,因为您会出现乱码数组的语义,下游代码不再知道“它在看什么”。

答案 1 :(得分:0)

似乎您需要在使用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]