簡體   English   中英

xarray 將單個值分配給一個變量/dataArray 最終分配給所有變量/dataArray

[英]xarray assigning individual values to one variable/dataArray ends up assigning to all variables/dataArray

我有一個腳本,我在其中創建了一個充滿 np.nan 的大型 xarray 數據集,然后在循環中分配單個值 with.loc (我也嘗試使用位置索引)( doc

我得到了一些很奇怪的東西。

這是我最小的可重現示例:

import xarray as xr
import numpy as np

levels = np.arange(0,3)
simNames = ['9airports_filter0dot7_v22']
airportList = ['Windhoek', 'Atlanta', 'Taipei']

emptyDA = xr.DataArray(np.nan, coords = [simNames, airportList, np.arange(0, 20428), levels], 
                       dims = ['simName', 'airport', 'profnum', 'level'])

ds = xr.Dataset({
    'iasi': emptyDA,
    'IM':   emptyDA,
    'IMS': emptyDA,
    'err': emptyDA,
    'sigma': emptyDA,
    'temp': emptyDA, 
    'dfs': emptyDA, 
    'ocf': emptyDA, 
    'rcf': emptyDA, 
    'time': emptyDA, 
    'surfPres': emptyDA })

ds = ds.assign_coords(time = ds.time) # pass time from variable to coord

ds['dfs'].loc['9airports_filter0dot7_v22', 'Windhoek', 0, 0] = 3

我將標量“3”分配給所有數據數組:

<xarray.Dataset>
Dimensions:   (simName: 1, airport: 3, profnum: 20428, level: 3)
Coordinates:
  * simName   (simName) <U25 '9airports_filter0dot7_v22'
  * airport   (airport) <U8 'Windhoek' 'Atlanta' 'Taipei'
  * profnum   (profnum) int64 0 1 2 3 4 5 ... 20423 20424 20425 20426 20427
  * level     (level) int64 0 1 2
Data variables:
    iasi      (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    IM        (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    IMS       (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    err       (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    sigma     (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    temp      (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    dfs       (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    ocf       (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    rcf       (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    time      (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan
    surfPres  (simName, airport, profnum, level) float64 3.0 nan nan ... nan nan 

雖然這個更簡單的代碼可以正常工作:

import xarray as xr
import numpy as np

ds = xr.Dataset({'var1': (('x', 'y'), [[np.nan, np.nan],[np.nan, np.nan]]), 'var2': (('x', 'y'), [[np.nan, np.nan], [np.nan, np.nan]])})

ds['var1'].loc[0, 0] = 1

好的,我明白了我的錯誤:沒有為每個新變量復制emptyDA,而是指向同一個object。 插入 emptyDA.copy() 而不是 emptyDA 可以解決問題。 我認為創建 xarray object 會復制數據。 謝謝你的幫助

出現此問題是因為當您使用 DataArrays 字典初始化xarray.Dataset時,它會生成 DataArrays 的淺表副本,從而允許每個具有不同的元數據,但不會復制底層 numpy arrays。

您可以根據您的問題通過一個小示例查看此行為。

首先,我將創建一個包含所有 NaN 的新 numpy 數組:

In [1]: import xarray as xr, numpy as np, pandas as pd

In [2]: np_arr = np.array([np.nan, np.nan, np.nan, np.nan])

In [3]: np_arr
Out[3]: array([nan, nan, nan, nan])

我們可以在這里看到實際的memory地址ID:

In [4]: hex(id(np_arr))
Out[4]: '0x1186570f0'

記住這個地址 - 我們會回到它: '0x1186570f0'

接下來,我們將創建一個包裝此 numpy 數組的 DataArray:

In [5]: da = xr.DataArray(np_arr, dims=['x'], coords=[range(4)])

In [6]: da
Out[6]:
<xarray.DataArray (x: 4)>
array([nan, nan, nan, nan])
Coordinates:
  * x        (x) int64 0 1 2 3

DataArray 本身獲得了一個新 ID,但底層數組只是指向相同的 numpy object 在'0x1186570f0'

In [7]: hex(id(da))
Out[7]: '0x118668460'

In [8]: hex(id(da.data))
Out[8]: '0x1186570f0'

當您使用 DataArrays 字典初始化 Dataset 時,xarray 會生成 arrays 的淺表副本。 請注意,對 DataArray 地址的引用已更改:

In [9]: ds = xr.Dataset({'var1': da, 'var2': da})

In [10]: hex(id(ds['var1']))
Out[10]: '0x1186d5340'

In [11]: hex(id(ds['var2']))
Out[11]: '0x1186e0fa0'

這允許每個數組具有不同的屬性/元數據

In [12]: ds['var1'].name
Out[12]: 'var1'

In [13]: ds['var2'].name
Out[13]: 'var2'

不過數據還是指向原來的numpy地址:

In [14]: hex(id(ds['var1'].data))
Out[14]: '0x1186570f0'

In [15]: hex(id(ds['var2'].data))
Out[15]: '0x1186570f0'

這是一件好事,因為這意味着使用 xarray 不會破壞您的 memory 使用,除非您告訴它這樣做。 但是,如果您願意,您必須告訴它復制數據。

您可以使用深層副本執行此操作,默認情況下xarray.DataArray.copy會執行此操作:

In [16]: ds = xr.Dataset({'var1': da.copy(), 'var2': da.copy()})

In [17]: hex(id(ds['var1'].data))
Out[17]: '0x1186b23f0'

In [18]: hex(id(ds['var2'].data))
Out[18]: '0x118660090'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM