Numpy ndarray:理解切片对象和“:”
Numpy ndarray: understanding slice objects and ":"
假设你有:
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]
的等价物?
似乎您需要在使用 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]
使用切片对象进行索引与使用整数进行索引具有不同的语义。使用单个整数进行索引会折叠/删除相应的维度,而使用切片进行索引永远不会这样做。
如果你想要沿着某个轴用单个整数进行索引的行为,你可以用一个切片和之后的一些重塑逻辑来模拟它;但最简单的解决方案是用相应的整数替换该切片。
或者,还有np.squeeze。绝对不要在没有 axis 关键字的情况下使用它,因为这是产生意外行为的代码的保证方法。但是只挤压那些你切片的轴会产生你想要的效果。
如果你允许我说一句小话:在更高的层次上,我怀疑你所追求的是一个 numpy 反模式。如果我必须制定 numpy 的第一条规则,那就不是仅仅因为它们恰好是单例就挤压轴。拥抱 ndarrays 并意识到更多的轴不会使您的代码更复杂,但它允许您表达数据的有意义的语义。您首先要切割该轴的事实表明该轴的大小根本不是 1;在特定情况下恰好如此。挤出单例维度将使任何下游代码几乎不可能以 numpythonic 和无错误的方式编写。如果你绝对必须压缩一个数组,比如在将它传递给绘图函数之前,请像对待 C++ 中的堆栈分配变量一样对待它,并且不要让对它的任何引用泄漏到当前范围之外,因为你会出现乱码该数组的语义,下游代码不再知道 'what is it looking at'.
假设你有:
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]
的等价物?
似乎您需要在使用 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]
使用切片对象进行索引与使用整数进行索引具有不同的语义。使用单个整数进行索引会折叠/删除相应的维度,而使用切片进行索引永远不会这样做。
如果你想要沿着某个轴用单个整数进行索引的行为,你可以用一个切片和之后的一些重塑逻辑来模拟它;但最简单的解决方案是用相应的整数替换该切片。
或者,还有np.squeeze。绝对不要在没有 axis 关键字的情况下使用它,因为这是产生意外行为的代码的保证方法。但是只挤压那些你切片的轴会产生你想要的效果。
如果你允许我说一句小话:在更高的层次上,我怀疑你所追求的是一个 numpy 反模式。如果我必须制定 numpy 的第一条规则,那就不是仅仅因为它们恰好是单例就挤压轴。拥抱 ndarrays 并意识到更多的轴不会使您的代码更复杂,但它允许您表达数据的有意义的语义。您首先要切割该轴的事实表明该轴的大小根本不是 1;在特定情况下恰好如此。挤出单例维度将使任何下游代码几乎不可能以 numpythonic 和无错误的方式编写。如果你绝对必须压缩一个数组,比如在将它传递给绘图函数之前,请像对待 C++ 中的堆栈分配变量一样对待它,并且不要让对它的任何引用泄漏到当前范围之外,因为你会出现乱码该数组的语义,下游代码不再知道 'what is it looking at'.