我可以使 Numpy 数组不可变吗?
Posted
技术标签:
【中文标题】我可以使 Numpy 数组不可变吗?【英文标题】:Can I make a Numpy array immutable? 【发布时间】:2022-01-20 11:34:50 【问题描述】:此帖https://***.com/a/5541452/6394617
建议一种使 Numpy 数组不可变的方法,使用 .flags.writeable = False
但是,当我测试这个时:
arr = np.arange(20).reshape((4,5))
arr.flags.writeable = False
arr
for i in range(5):
np.random.shuffle(arr[:,i])
arr
数组在原地打乱,甚至没有警告。
问题:有没有办法使数组不可变?
背景:
对于上下文,我正在做机器学习,我有特征数组 X,它是浮点数和标签数组 y,它是整数。
我是 Scikit-learn 的新手,但从我读过的内容来看,fit 方法似乎将数组打乱了。也就是说,当我创建两个数组,为数据拟合模型,然后检查数组时,它们是原始顺序的。所以我只是不熟悉 Scikit-learn 是如何洗牌的,也无法在网上找到一个简单的解释。
我正在使用许多不同的模型,并在两者之间进行一些预处理,我担心在某些时候我的两个数组可能会被打乱,从而使行不再适当地对应。
如果我能让数组不可变,我会放心。我确信我可以切换到元组而不是 Numpy 数组,但我怀疑这会更复杂且更慢。
【问题讨论】:
我会搞砸术语,但arr[:, i]
返回的内容类似于数据的“视图”,而不是数组本身。 np.random.shuffle(x)
会报错
scikit-learn 的 fit
不应该洗牌。如果它洗牌任何东西,它应该做整行。
@QuangHoang,我知道 scikit-learn 默认会随机播放(行,而不是列),但是当我在 clf.fit(X,y)
之前调用 X.flags.writeable = False
并且没有导致任何错误时,我感到很惊讶,因为它在我看来,fit
会尝试将数据改组,但不应该这样做。所以我不确定 scikit-learn 库是如何打乱数据的。我还没有深入研究每一行源代码,也没有时间,这就是为什么我希望有某种方法可以锁定数组,以防止 any 对其进行更改。
问题不在于arr[:, i]
是一个视图,而在于它是一个一维数组。当输入是一维数组时,shuffle
方法似乎不尊重writeable
标志。例如。 x = np.arange(5); x.flags.writeable = False; np.random.shuffle(x)
成功。这可能是shuffle
方法中的一个错误。
@WarrenWeckesser,太好了,谢谢!你想把它作为答案发布,以便将来如果有人有这个问题,他们会发现他们只需要确保拥有最新版本的 NumPy?
【参考方案1】:
这是 numpy 1.22 及更早版本中numpy.random.shuffle
中的一个错误。当数组是一维时,该函数不尊重输入数组的writeable
标志。
numpy.random.Generator.shuffle
有同样的问题,numpy.random.Generator.permuted
不尊重任何维度数组的 writeable
标志。
这在 NumPy 的主要开发分支中一直是fixed,因此 NumPy 版本 1.23.0 及更高版本不会出现此错误。请注意,NumPy 1.22.0 尚未发布,但可作为候选发布版。修复发生在 1.22 分支之后,所以修复不会在 1.22.0 中。
【讨论】:
以上是关于我可以使 Numpy 数组不可变吗?的主要内容,如果未能解决你的问题,请参考以下文章
为包含可变长度序列的数组的输出标签创建分类 numpy 数组
包含具有可变形状的多维 numpy 数组的 numpy 数组