【问题标题】:Sparse DataArray Xarray search稀疏 DataArray Xarray 搜索
【发布时间】:2019-01-18 23:41:23
【问题描述】:

在 xarray 中使用 DataArray 对象查找所有具有值 != 0 的单元格的最佳方法是什么。

例如在熊猫中我会这样做

df.loc[df.col1 > 0]

我正在尝试查看 3 维脑成像数据的具体示例。

first_image_xarray.shape
(140, 140, 96)
dims = ['x','y','z']

查看xarray.DataArray.where 的文档似乎我想要这样的东西:

first_image_xarray.where(first_image_xarray.y + first_image_xarray.x  > 0,drop = True)[:,0,0]

但我仍然得到带有零的数组。

<xarray.DataArray (x: 140)>
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0., -0.,  0., -0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
Dimensions without coordinates: x

另外 - 一个附带问题 - 为什么会有一些负零?这些值是否四舍五入和 -0。实际上等于-0.009876之类的东西?

【问题讨论】:

  • 如果使用非常稀疏的矩阵,我建议您阅读有关如何使用稀疏矩阵的信息。特别是您可以阅读有关libsvm 数据表示的信息。

标签: python pandas python-xarray


【解决方案1】:

(回答主要问题)

你快到了。但是,细微的语法差异在这里会产生很大的不同。一方面,这是使用 “基于值” 掩码过滤 &gt;0 值的解决方案。

# if you want to DROP values which do not suffice a mask condition
first_image_xarray[:,0,0].where(first_image_xarray[:,0,0] > 0, drop=True)

# if you want to KEEP values which do not suffice a mask condition as nan
first_image_xarray[:,0,0].where(first_image_xarray[:,0,0] > 0, np.nan)

另一方面,你的尝试没有如你所愿的原因是因为first_image_xarray.x,它指的是数组中元素的索引(在x方向) 而不是引用元素的。因此,只有输出的第一个元素应该是 nan 而不是 0,因为它不能满足切片 [:,0,0] 中的掩码条件。是的,您正在创建一个 “基于索引” 掩码。

以下小实验(希望如此)阐明了这一关键差异。

假设我们有DataArray,其中仅包含01(尺寸与问题(140,140,96) 的原始帖子(OP)对齐)。首先,让我们像 OP 一样根据 index 对其进行屏蔽:

import numpy as np
import xarray as xr

np.random.seed(0)
# create a DataArray which randomly contains 0 or 1 values
a = xr.DataArray(np.random.randint(0, 2, 140*140*96).reshape((140, 140, 96)), dims=('x', 'y', 'z'))


# with this "index-based" mask, only elements where index of both x and y are 0 are replaced by nan
a.where(a.x + a.y > 0, drop=True)[:,0,0]

Out:
<xarray.DataArray (x: 140)>
array([ nan,   0.,   1.,   1.,   0.,   0.,   0.,   1.,   0.,   0.,   0.,   0.,
         0.,   1.,   0.,   1.,   0.,   1.,   0.,   0.,   0.,   1.,   0.,   0.,
         1.,   1.,   0.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,
         1.,   1.,   0.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   0.,   1.,
         1.,   0.,   0.,   0.,   1.,   1.,   1.,   0.,   0.,   1.,   0.,   0.,
         1.,   0.,   1.,   1.,   0.,   0.,   1.,   0.,   0.,   1.,   1.,   1.,
         0.,   0.,   0.,   1.,   1.,   0.,   1.,   0.,   1.,   1.,   0.,   0.,
         0.,   0.,   1.,   1.,   0.,   1.,   1.,   1.,   1.,   0.,   1.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   1.,   0.,   1.,   1.,   0.,   0.,
         0.,   0.,   1.,   0.,   1.,   0.,   0.,   0.,   0.,   1.,   0.,   1.,
         0.,   0.,   1.,   0.,   0.,   0.,   0.,   0.,   1.,   1.,   0.,   0.,
         0.,   1.,   0.,   0.,   1.,   0.,   0.,   1.])
Dimensions without coordinates: x

使用上面的掩码,只有xyindex元素都是0的元素变成nan,其余的根本没有改变或删除.

相比之下,建议的解决方案根据DataArray 元素的 屏蔽DataArray

# with this "value-based" mask, all the values which do not suffice the mask condition are dropped
a[:,0,0].where(a[:,0,0] > 0, drop=True)

Out:
<xarray.DataArray (x: 65)>
array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,
        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,
        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,
        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,
        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])
Dimensions without coordinates: x

这会根据DataArray 元素的成功删除所有不满足掩码条件的值。


(回答附带问题)

至于DataArray-00的起源,从负向或正向舍入到0的值是可能的:在此进行了相关讨论How to eliminate the extra minus sign when rounding negative numbers towards zero in numpy?下面是一个小这种情况的例子。

import numpy as np
import xarray as xr

xr_array = xr.DataArray([-0.1, 0.1])

# you can use either xr.DataArray.round() or np.round() for rounding values of DataArray

xr.DataArray.round(xr_array)

Out:
<xarray.DataArray (dim_0: 2)>
array([-0.,  0.])
Dimensions without coordinates: dim_0

np.round(xr_array)

Out:
<xarray.DataArray (dim_0: 2)>
array([-0.,  0.])
Dimensions without coordinates: dim_0

附带说明,在 NumPy 数组中获取 -0 的另一种可能性是 numpy.set_printoptions(precision=0),它隐藏在小数点以下,如下所示(但我知道这次不是这种情况,因为您使用的是 DataArray ):

import numpy as np

# default value is precision=8 in ver1.15
np.set_printoptions(precision=0)

np.array([-0.1, 0.1])

Out:
array([-0.,  0.])

无论如何,我最好的猜测是,在数据准备和预处理阶段转换为-0 应该是手动和有意的,而不是自动的。

希望这会有所帮助。

【讨论】:

  • 谢谢!标记为正确 - 想确保您获得赏金。我今天晚些时候试试。对于“-0 舍入”,您的解释完全有道理。我会谷歌什么来找出为什么或如何自动四舍五入。我的意思是:numpy 是舍入它们还是 xarray?
  • @Liam Hanninen 我在下半场添加了更多上下文。我无法得出对它们进行舍入是 numpy 还是 xarray 的结论(因为两者都有可能),但我最好的猜测是舍入是在数据预处理阶段故意进行的。
猜你喜欢
  • 1970-01-01
  • 2020-10-26
  • 2017-01-30
  • 1970-01-01
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 2021-02-02
相关资源
最近更新 更多