【问题标题】:Xarray reads data in file as coordinates, apparently indexing coordinates, how do I convert the actual data from coordinates to data variables?Xarray 将文件中的数据读取为坐标,显然是索引坐标,如何将实际数据从坐标转换为数据变量?
【发布时间】:2020-05-28 05:27:13
【问题描述】:

我正在处理位于以下位置的文件:

https://satdat.ngdc.noaa.gov/sem/poes/data/processed/ngdc/uncorrected/full/2013/metop01/poes_m01_20130525_proc.nc

当我使用 xarray 阅读时,

ds = xr.open_dataset('poes_m01_20130525_proc.nc')

所有变量都作为坐标读入,其中至少有一些作为索引坐标。我只知道最后一点,因为当我尝试将它们转换为变量时,

ds.reset_coords()

我得到了错误,

ValueError: cannot remove index coordinates with reset_coords.  The error appears to include all of the variables (there is a very long list).  

我可以将所有坐标变量转换为一个 numpy 数组并手动重建一个新的数据集。但是,我对 xarray 很陌生。有没有更优雅的方法来做到这一点?例如,我可以将索引坐标转换为非索引坐标,然后使用reset_coords?另外,我如何判断哪些坐标是索引坐标,哪些不是?

或者,更好的是,在读取我不知道要使用的文件时,我应该使用一些选项。我无法识别文档中的任何建议,但文档中有很多我不理解的内容。

感谢您的帮助!

【问题讨论】:

    标签: python-xarray


    【解决方案1】:

    正如您所猜测的,为了能够将坐标转换为数据变量,它必须是非索引坐标。您将识别索引坐标,因为当列出坐标时,它们前面有一个*。在您的示例中,看起来每个变量都被假定为它自己的坐标(不知道为什么,我不是 NetCDF 专家)。

    要将索引坐标转换为非索引坐标,可以使用reset_index,这需要指定要重置的索引。我冒昧地假设数据集中的前几个坐标被正确设置为坐标,其余的应该是数据变量。在这种情况下,下面的代码可以解决问题:

    var_names = list(
        set(ds.dims) - 
        {"time", "year", "day", "msec", "satID", "sat_direction", "alt", "lat", "lon"}
    )
    clean_ds = ds.reset_index(var_names).reset_coords()
    

    这给我们留下了一个不是很有用的数据集。 reset_index 在每个变量名称的末尾添加了一个_(以区分非索引坐标和同名维度)。您可能想要做类似于其他答案中所做的事情:Xarray: Make two DataArrays in the same Dataset use the same coordinate system

    一些想法:

    获取所有变量以 time 作为维度

    coord_names = ["time", "year", "day", "msec", "satID", "sat_direction", "alt", "lat", "lon"]
    clean_ds = clean_ds.reset_index(coord_names + [])
    clean_ds = clean_ds.rename({name: "time_" for name in clean_ds.dims})
    

    然后,重命名变量和坐标(以及time_ dim)以删除名称中的尾随下划线:

    clean_ds.rename({f"{name}_": name for name in var_names+coord_names})
    

    如果我们使用rename_vars,则维度time_ 不会被重命名,它可以在之后重命名以保持时间坐标和暗淡不同。

    在所有重命名和重组之后,原始数据集中的属性可以再次添加到clean_ds

    for var_name in ds.coords:
        clean_ds[var_name] = clean_ds[var_name].assign_attrs(ds[var_name].attrs)
    

    【讨论】:

    • 这也回答了我关于如何创建非索引坐标的问题。是的,我确实希望所有这些都作为坐标,但是当我使用其他方法来简单地构建新数据集时,我还没有学会如何创建具有多个等效坐标的数据集。我总是以多个维度结束。谢谢!
    • 如果您从头开始创建 xarray 结构,您还可以指定每个对象的尺寸和坐标:参见 creating a DataArray 以及 creating a DatasetDataset API page。在最后一个链接中,请注意如何使用 Datasets,例如,您可以将 dict 作为 data 传递,并且根据字典的格式,它将被理解为 data_var 或坐标
    • 所以,我可能过早宣布胜利。我刚刚发现,当我使用上面的方法时,我丢失了所有的变量和坐标属性信息。有没有办法保存它?
    • 我没有意识到数据数组有属性,但这完全出乎意料,感谢您指出。我已经更新了使用原始 ds 再次将属性添加到 clean_ds 中的答案,我会尝试更深入地挖掘,可能是一个错误:/
    • 谢谢,如果是错误请告诉我!我相信 pandas 数据框可以具有属性,但不能保证它们能够在所有操作中存活。我认为 xarray 可以保证这一点,这是它的吸引力之一。我希望这只是一个可以修复的错误,而不是一个无法修复的不被接受的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    相关资源
    最近更新 更多