将一系列的xarray.DataArrays转换为numpy数组

3

在此输入图像描述在此输入图像描述我正在使用名为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文件的制表符不对齐,请谅解。感激任何帮助!


你能打印一下这个带有嵌套DataArray的DataFrame的示例吗?比如前几个元素。 - shoyer
我发布了一系列截图和原始DataFrame的另一张截图。 - Kingle
1个回答

5
感谢分享数据样例。
首先,将xarray.DataArray对象作为标量嵌套在pandas.DataFrame中是一种非常不标准的处理xarray和pandas的方式。我不建议这样做。如果每个条目都是共享(部分)相同维度的DataArray,则处理数据的最简单方法是将其作为xarray.Dataset处理,这是xarray版本的多维pandas.DataFrame。
话虽如此,将数据从这种格式转换为更易于使用的非嵌套对象应该很简单。最好的起点是Series.values,它提取一个列作为1D numpy数组。然后,您可以遍历系列并使用.values将每个DataArray转换为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应该做的。)

谢谢。我已经成功使用了numpy数组。但是,由于某种原因,Spyder的变量浏览器中没有显示xarrays。这可能是什么原因呢?我想我更熟悉Numpy,所以这个选项对我来说可能已经足够了。非常感谢! - Kingle
@shoyer,这个xr.concat函数是否可以像flattening/stack()数据一样工作? - Krishnaap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接