为什么操作数组会永久占用这么多内存?

Why does manipulating xarrays takes up so much memory permanently?

我是 Xarray 的新手(在 jupyter notebooks 中使用它),到目前为止一切都很顺利,除了当我开始查看我的函数使用了多少 RAM 时(例如 htop) ,这让我感到困惑(我在 stackexchange 上没有找到任何东西)。

我将月度数据与年均值相结合,同时考虑月份长度、屏蔽 nan 值以及仅使用特定月份,这需要使用 groupby 和 resample。 从使用内存分析器可以看出,这些操作暂时占用了 ~15gm RAM,这本身不是问题,因为我手头有 64gb RAM。 尽管如此,似乎某些内存被永久阻塞,即使我在函数中调用这些方法也是如此。对于下面的函数,它会阻塞 ~4gb 的内存,尽管生成的 xarray 只有 ~440mb 的大小(55*10**6 float 64entries),对于更复杂的操作,它会阻塞更多的内存。 在函数内部显式使用 del 、 gc.collect() 或 Dataarray.close() 并没有改变任何东西。

根据月度数据计算加权年度平均值的基本函数如下所示:

import xarray as xr
test=xr.open_dataset(path)['pr']

def weighted_temporal_mean(ds):
    """
    Taken  from https://ncar.github.io/esds/posts/2021/yearly-averages-xarray/
    Compute yearly average from monthly data taking into account month length and 
    masking nan values
    """
    # Determine the month length
    month_length = ds.time.dt.days_in_month

    # Calculate the weights
    wgts = month_length.groupby("time.year") / month_length.groupby("time.year").sum()

    # Setup our masking for nan values
    cond = ds.isnull()
    ones = xr.where(cond, 0.0, 1.0)

    # Calculate the numerator
    obs_sum = (ds * wgts).resample(time="AS").sum(dim="time")

    # Calculate the denominator
    ones_out = (ones * wgts).resample(time="AS").sum(dim="time")

    # Return the weighted average
    return obs_sum / ones_out

wm=weighted_temporal_mean(test)
print("nbytes in MB:", wm.nbytes / (1024*1024))

知道如何确保释放内存吗,或者我是否忽略了某些东西而这种行为实际上是预期的?

谢谢!

我对这种行为的唯一假设是一些涉及传入 ds 的操作就地修改了它,增加了它的大小,因为除了返回的对象之外,这是唯一的对象应该在函数执行后继续存在。

在函数为 运行 之后,在用作输入的 ds 结构上使用 del 可以很容易地验证这一点。 (如果你之后需要数据,re-read它,或者在调用函数之前进行深度复制)。

如果这不能解决问题,那么这是 xarray 项目的问题,我建议您在他们的项目中打开一个问题。