![](/img/trans.png)
[英]renaming __xarray_dataarray_variable__ in xarray 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.