【发布时间】:2017-07-20 09:34:12
【问题描述】:
我正在尝试将多维数据集中超过某个数字的所有值设置为零。
我试过以下点头方式:
cube_tot_lo.data = np.where(cube_tot_lo.data < 1.0e19, cube_tot_lo.data, 0.0)
但它是一个大立方体,会杀死内存。我想知道是否有更好的方法来做到这一点?
感谢大家的宝贵时间!
【问题讨论】:
标签: python python-2.7 python-iris
我正在尝试将多维数据集中超过某个数字的所有值设置为零。
我试过以下点头方式:
cube_tot_lo.data = np.where(cube_tot_lo.data < 1.0e19, cube_tot_lo.data, 0.0)
但它是一个大立方体,会杀死内存。我想知道是否有更好的方法来做到这一点?
感谢大家的宝贵时间!
【问题讨论】:
标签: python python-2.7 python-iris
(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”的任何引用都会将所有数据提取到一个真正的内存数组中,而例如只需保存多维数据集或计算统计数据就可以避免这种情况。
因此,真正大立方体的可用性在很大程度上取决于您最终如何处理内容。
Iris 现在在即将发布的 2.0 版的文档中对此有了更全面的说明: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)
这使得派生多维数据集具有延迟数据计算。由于可以在时机成熟时以“块”的形式进行处理,因此可以大大减少内存使用量。
【讨论】: