1

我正在尝试将多维数据集中超过某个数字的所有值设置为零。

我尝试了以下点头方式:

cube_tot_lo.data = np.where(cube_tot_lo.data < 1.0e19, cube_tot_lo.data, 0.0)

但它是一个大立方体,会杀死记忆。我想知道是否有更好的方法来做到这一点?

谢谢大家的时间!

4

1 回答 1

2

(1) 一个更常见的 numpy 习语是:

cube.data[cube.data < threshold_value] = 0.0

我认为这应该会对内存问题产生一些印象,因为它不会计算一个全新的浮点数组来分配回去。
但是,它确实需要为 创建一个数据大小的布尔数组cube.data < threshold_value,因此它可能仍然无法解决您的问题。

(2) 一个非常简单的性能改进可能是分段执行此操作,如果您有一个可以切片的维度,例如具有几十个级别的典型 Z 维度?然后你可以只划分任务,例如,对于一个 4d 立方体的暗淡 t,z,y,x :--

for i in range(nz):
    part = cube.data[:, iz]
    part[part < threshold_value] = 0.0

如果您的多维数据集已经包含“真实”而不是“惰性”数据,这也应该很好用。

(3) 但是,我想知道您的关键问题是否可能是一次获取所有数据本身太大了
这在 Iris 中是完全可能的,因为它使用延迟加载:因此,对“cube.data”的任何引用都会将所有数据提取到一个真正的内存数组中,而例如简单地保存多维数据集或计算统计数据就可以避免这种情况。
因此,真正大立方体的可用性关键取决于您最终如何处理内容。

在即将发布的 2.0 版的文档中,Iris 现在对此有了更全面的说明:https ://scitools-docs.github.io/iris/master/userguide/real_and_lazy_data.html

例如,在即将到来的 iris v2 中使用 Dask,就可以使用 dask 来有效地执行此操作。就像是:

data = cube.lazy_data()
data = da.where(data < threshold_value, data, 0.0)
zapped_cube = cube.copy(data=data)

这使得派生多维数据集具有延迟数据计算。由于可以在时机成熟时以“块”的形式对其进行处理,因此可以大大减少内存使用量。

于 2017-07-20T10:18:48.507 回答