我可以使 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 数组不可变吗?的主要内容,如果未能解决你的问题,请参考以下文章

我们可以在 C++ 中创建可变长度数组吗

为包含可变长度序列的数组的输出标签创建分类 numpy 数组

包含具有可变形状的多维 numpy 数组的 numpy 数组

c++中有可变长度数组吗?

iOS 中 关于 NSUserDefault中存储可变数组的问题

OpenCL中不允许使用可变长度数组声明 - 为什么?