将一系列 xarray.DataArrays 转换为 numpy 数组
Converting a series of xarray.DataArrays to a numpy array
我正在使用名为 PySD 的软件包进行系统动力学建模。 PySD 将模型从 Vensim(系统动力学建模包)转换为 python,并允许用户用比 Vensim 更复杂的例程替换各种方程式。我是 运行 具有各种下标的模型,这会创建一种不寻常的输出格式。输出被读入数据框,其下标元素的单个值最终为 xarray.DataArrays。我想知道如何获取 xarray.DataArrays 的一列(最终成为一个系列)并将其转换为二维数组,第二维是下标的数量。
import pysd
import numpy as np
model=pysd.load("Example.py")
stocks=model.run
pop=np.array(Population) #Creates an object array
Population=stocks.Populaton #Creates a series
#How to get an array of population values for each country?
example.py代码如下(请记住这是一个任意示例来说明问题)
from __future__ import division
import numpy as np
from pysd import utils
import xarray as xr
from pysd.functions import cache
from pysd import functions
_subscript_dict = {
'Country': ['Canada', 'USA', 'China', 'Norway', 'India', 'England',
'Mexico', 'Yemen']
}
_namespace = {
'TIME': 'time',
'Time': 'time',
'Deaths': 'deaths',
'Births': 'births',
'Population': 'population',
'Birth rate': 'birth_rate',
'Murder rate': 'murder_rate',
'Natural death rate': 'natural_death_rate',
'FINAL TIME': 'final_time',
'INITIAL TIME': 'initial_time',
'SAVEPER': 'saveper',
'TIME STEP': 'time_step'
}
@cache('step')
def deaths():
return murder_rate() * population() + natural_death_rate() * population()
@cache('step')
def births():
return birth_rate() * population()
@cache('step')
def population():
return integ_population()
@cache('run')
def birth_rate():
return utils.xrmerge([
xr.DataArray(
data=[5., 5., 5., 5., 5., 5., 5., 5.],
coords={
'Country':
['Canada', 'USA', 'China', 'Norway', 'India', 'England', 'Mexico', 'Yemen']
},
dims=['Country']),
xr.DataArray(data=[10.], coords={'Country': ['Mexico']}, dims=
['Country']),
xr.DataArray(data=[8.], coords={'Country': ['Yemen']}, dims=
['Country']),
])
@cache('step')
def murder_rate():
return time()
@cache('run')
def natural_death_rate():
return utils.xrmerge([
xr.DataArray(
data=[3., 3., 3., 3., 3., 3., 3., 3.],
coords={
'Country':
['Canada', 'USA', 'China', 'Norway', 'India', 'England', 'Mexico', 'Yemen']
},
dims=['Country']),
xr.DataArray(data=[5.], coords={'Country': ['Yemen']}, dims=['Country']),
xr.DataArray(data=[5.], coords={'Country': ['Mexico']}, dims=['Country']),
])
@cache('run')
def final_time():
return 100
@cache('run')
def initial_time():
return 0
@cache('step')
def saveper():
return time_step()
@cache('run')
def time_step():
return 1
def _init_population():
return xr.DataArray(
data=np.ones([8]) * 10,
coords={
'Country': ['Canada', 'USA', 'China', 'Norway', 'India', 'England', 'Mexico', 'Yemen']
},
dims=['Country'])
@cache('step')
def _dpopulation_dt():
return births() - deaths()
integ_population = functions.Integ(lambda: _dpopulation_dt(), lambda: _init_population())
如果 example.py 文件选项卡不在一行,我深表歉意。如有任何帮助,我们将不胜感激!
感谢您分享此数据的示例。
首先,将 xarray.DataArray
对象作为标量嵌套在 pandas.DataFrame
中是使用 xarray 和 pandas 的非常不标准的方式。我不推荐它。如果每个条目都是一个共享(某些)相同维度的 DataArray,那么处理数据的最简单方法是作为 xarray.Dataset
,xarray 版本的多维 pandas.DataFrame
.
也就是说,将您的数据从这种格式转换为更易于使用的未嵌套对象应该很简单。最好的起点是 Series.values
,它将列提取为一维 numpy 数组。然后您可以遍历该系列并将每个 DataArray
也转换为带有 .values
的 numpy 数组。放在一起:
population_numpy_array = np.stack(
[data_array.values for data_array in df['Population'].values])
或者,您可以使用 xarray 堆叠 DataArray 对象。这将保留标签,使您的数据更易于使用:
population_data_array = xr.concat(df['Population'].values, dim='row_name')
您甚至可以将完整对象转换为 xarray.Dataset
以进行联合分析:
ds = xr.Dataset({k: xr.concat(df[k].values, dim='row_name') for k in df.keys()})
(可以说,这正是 PySD 应该做的。)
import pysd
import numpy as np
model=pysd.load("Example.py")
stocks=model.run
pop=np.array(Population) #Creates an object array
Population=stocks.Populaton #Creates a series
#How to get an array of population values for each country?
example.py代码如下(请记住这是一个任意示例来说明问题)
from __future__ import division
import numpy as np
from pysd import utils
import xarray as xr
from pysd.functions import cache
from pysd import functions
_subscript_dict = {
'Country': ['Canada', 'USA', 'China', 'Norway', 'India', 'England',
'Mexico', 'Yemen']
}
_namespace = {
'TIME': 'time',
'Time': 'time',
'Deaths': 'deaths',
'Births': 'births',
'Population': 'population',
'Birth rate': 'birth_rate',
'Murder rate': 'murder_rate',
'Natural death rate': 'natural_death_rate',
'FINAL TIME': 'final_time',
'INITIAL TIME': 'initial_time',
'SAVEPER': 'saveper',
'TIME STEP': 'time_step'
}
@cache('step')
def deaths():
return murder_rate() * population() + natural_death_rate() * population()
@cache('step')
def births():
return birth_rate() * population()
@cache('step')
def population():
return integ_population()
@cache('run')
def birth_rate():
return utils.xrmerge([
xr.DataArray(
data=[5., 5., 5., 5., 5., 5., 5., 5.],
coords={
'Country':
['Canada', 'USA', 'China', 'Norway', 'India', 'England', 'Mexico', 'Yemen']
},
dims=['Country']),
xr.DataArray(data=[10.], coords={'Country': ['Mexico']}, dims=
['Country']),
xr.DataArray(data=[8.], coords={'Country': ['Yemen']}, dims=
['Country']),
])
@cache('step')
def murder_rate():
return time()
@cache('run')
def natural_death_rate():
return utils.xrmerge([
xr.DataArray(
data=[3., 3., 3., 3., 3., 3., 3., 3.],
coords={
'Country':
['Canada', 'USA', 'China', 'Norway', 'India', 'England', 'Mexico', 'Yemen']
},
dims=['Country']),
xr.DataArray(data=[5.], coords={'Country': ['Yemen']}, dims=['Country']),
xr.DataArray(data=[5.], coords={'Country': ['Mexico']}, dims=['Country']),
])
@cache('run')
def final_time():
return 100
@cache('run')
def initial_time():
return 0
@cache('step')
def saveper():
return time_step()
@cache('run')
def time_step():
return 1
def _init_population():
return xr.DataArray(
data=np.ones([8]) * 10,
coords={
'Country': ['Canada', 'USA', 'China', 'Norway', 'India', 'England', 'Mexico', 'Yemen']
},
dims=['Country'])
@cache('step')
def _dpopulation_dt():
return births() - deaths()
integ_population = functions.Integ(lambda: _dpopulation_dt(), lambda: _init_population())
如果 example.py 文件选项卡不在一行,我深表歉意。如有任何帮助,我们将不胜感激!
感谢您分享此数据的示例。
首先,将 xarray.DataArray
对象作为标量嵌套在 pandas.DataFrame
中是使用 xarray 和 pandas 的非常不标准的方式。我不推荐它。如果每个条目都是一个共享(某些)相同维度的 DataArray,那么处理数据的最简单方法是作为 xarray.Dataset
,xarray 版本的多维 pandas.DataFrame
.
也就是说,将您的数据从这种格式转换为更易于使用的未嵌套对象应该很简单。最好的起点是 Series.values
,它将列提取为一维 numpy 数组。然后您可以遍历该系列并将每个 DataArray
也转换为带有 .values
的 numpy 数组。放在一起:
population_numpy_array = np.stack(
[data_array.values for data_array in df['Population'].values])
或者,您可以使用 xarray 堆叠 DataArray 对象。这将保留标签,使您的数据更易于使用:
population_data_array = xr.concat(df['Population'].values, dim='row_name')
您甚至可以将完整对象转换为 xarray.Dataset
以进行联合分析:
ds = xr.Dataset({k: xr.concat(df[k].values, dim='row_name') for k in df.keys()})
(可以说,这正是 PySD 应该做的。)