DataArray 删除简单计算中的属性

Posted

技术标签:

【中文标题】DataArray 删除简单计算中的属性【英文标题】:DataArray deletes Attributes in simple computation 【发布时间】:2022-01-14 06:37:40 【问题描述】:

我注意到,如果您有一个 xArray DatarArray 并对其执行简单(!)计算,则属性会被“删除”。

例子:

example            = xr.DataArray(np.array([1,2,3]), attrs='one':1)
without_Attributes = example*3

另一方面,如果您使用 numpy 特定函数(例如 .round(x)、..),则属性仍然存在。对此有合理的解释吗?有没有办法在不丢失属性的情况下将 DataArray 相乘?

【问题讨论】:

【参考方案1】:

来自"what is your approach to metadata?" 上的 xarray 文档:

我们坚信标记数据的力量!除了维度和坐标,xarray 还支持全局 (Dataset) 和变量特定 (DataArray) 属性 (attrs) 形式的任意元数据。

标签的自动解释功能强大,但也降低了灵活性。使用 xarray,我们在库可以理解的标签(dimscoords)与用户和用户代码的标签(attrs)之间划清界限。例如,我们不会自动解释和强制执行单位或CF conventions。 (一个例外是与 netCDF 文件之间的序列化。)

这种选择的一个含义是,除非明确标记,否则我们不会通过大多数操作传播attrs(某些方法具有keep_attrs 选项,并且有一个全局标记用于将其设置为始终为真或假)。同样,xarray 在组合数组和数据集时不会检查attrs 之间的冲突,除非使用选项compat='identical' 明确请求。指导原则是不应该让元数据成为障碍。

您可以使用xr.set_options 在 xarray 中设置全局选项:

In [14]: xr.set_options(keep_attrs=True)
Out[14]: <xarray.core.options.set_options at 0x133ef58e0>

现在,属性被保留了

In [15]: example * 3
Out[15]:
<xarray.DataArray (dim_0: 3)>
array([3, 6, 9])
Dimensions without coordinates: dim_0
Attributes:
    one:      1

请注意,xarray 不会对这些属性做任何“智能”操作,这就是为什么默认行为是将它们放入计算中的原因。例如,一个带有单位的简单示例显示了设置 keep_attrs=True 会如何偏离轨道:

In [17]: dist = xr.DataArray(np.array([1,2,3]), attrs='units': 'm')
    ...: dist
Out[17]:
<xarray.DataArray (dim_0: 3)>
array([1, 2, 3])
Dimensions without coordinates: dim_0
Attributes:
    units:    m

In [18]: rate = xr.DataArray(np.array([2, 2, 2]), attrs='units': 'm/s')
    ...: rate
Out[18]:
<xarray.DataArray (dim_0: 3)>
array([2, 2, 2])
Dimensions without coordinates: dim_0
Attributes:
    units:    m/s

In [19]: dist / rate
Out[19]:
<xarray.DataArray (dim_0: 3)>
array([0.5, 1. , 1.5])
Dimensions without coordinates: dim_0
Attributes:
    units:    m

如果您想使用 xarray 显式处理计算中的单元,请查看 pint-xarray,这是将 pint project 的显式单元处理与 xarray 集成的努力。这个项目是实验性的,API 不稳定,但最近 pint-xarray 的工作人员和 xarray 的核心团队都在朝着同一个方向发展,所以我不认为这种协调会消失。

解决方法(或者也许是世界上最好的?)

请注意,由于 DatasetDataArray 属性只是字典,因此保存它们很容易:

In [22]: result = example * 3
    ...: result.attrs.update(example.attrs)

In [23]: result
Out[23]:
<xarray.DataArray (dim_0: 3)>
array([3, 6, 9])
Dimensions without coordinates: dim_0
Attributes:
    one:      1

您甚至可以独立于 DataArray 或 Dataset 使用它们:


In [25]: ds = xr.open_dataset('my_well_documented_file.nc')

In [26]: source_attrs = ds.attrs

In [23]: result = xr.Dataset('new_var': ds.varname * 3)

In [24]: result.attrs.update(
    ...:     # custom new attrs
    ...:     method='multiplied varname by 3',
    ...:     updated=pd.Timestamp.now(tz='US/Pacific').strftime('%c'),
    ...:     # carry forward attrs from input file
    ...:     **source_attrs[k] for k in ['author', 'contact'],
    ...: )

所以我通常采用的方法是在计算结束时显式复制我想要的属性。而且,如果需要,您可以使用 xarray-pint 显式处理单元,然后将其他元数据作为字典传递。

【讨论】:

非常感谢朋友!

以上是关于DataArray 删除简单计算中的属性的主要内容,如果未能解决你的问题,请参考以下文章

删除 Selenium WebDriver 中的只读属性

Vue.js 删除渲染函数中的 contenteditable 属性

EF4 CTP5 POCO 中的软删除、导航属性

删除 firstObject 时,Ember 计算属性不更新视图

Objective-C/iOS:如何从 CoreData 中的属性中删除“值”?

windows如何查看删除记录