Python 如何沿一维应用函数并将结果保存为数据集中的新变量?

Python 如何沿一维应用函数并将结果保存为数据集中的新变量?,python,arrays,numpy,pandas,python-xarray,Python,Arrays,Numpy,Pandas,Python Xarray,假设我有一个这样的数据集 nx1, nx2, nx3 = 5, 3, 20 ds = xray.Dataset() ds.coords.update({'x1': ('x1', range(nx1)), 'x2': ('x2', range(nx2)), 'x3': ('x3', range(nx3))}) ds['A'] = (['x1', 'x2', 'x3'], np.random.randn(nx1, nx2

假设我有一个这样的数据集

nx1, nx2, nx3 = 5, 3, 20

ds = xray.Dataset()
ds.coords.update({'x1': ('x1', range(nx1)), 
                  'x2': ('x2', range(nx2)), 
                  'x3': ('x3', range(nx3))})

ds['A'] = (['x1', 'x2', 'x3'], np.random.randn(nx1, nx2, nx3))
ds['B'] = (['x1', 'x2', 'x3'], np.random.randn(nx1, nx2, nx3))
required_shape = (len(ds.coords['x1']), 
                  len(ds.coords['x2']),
                  len(ds.coords['x3']))

if 'C' not in ds:
    ds.update({'C': (['x1', 'x2', 'x3'], np.zeros(required_shape))})

for ix1, x1 in enumerate(ds.coords['x1']):
    for ix2, x2 in enumerate(ds.coords['x2']):
        args = dict(x1=ix1, x2=ix2)
        a = ds['A'][args]
        b = ds['B'][args]
        c = func(a.values, b.values)
        ds['C'][args] = c
以及一个函数
func
,该函数将a和B作为输入变量,但它沿着
x3
维度工作,只接受形状
(nx3,)
的数组,并输出形状
(nx3,)
的数组。如果我想将此函数应用于上述数据集,并将结果保存为一个名为C的新变量,请按照以下方法执行:

required_shape = (len(ds.coords['x1']), 
                  len(ds.coords['x2']),
                  len(ds.coords['x3']))

if 'C' not in ds:
    ds.update({'C': (['x1', 'x2', 'x3'], np.zeros(required_shape))})

for ix1, x1 in enumerate(ds.coords['x1']):
    for ix2, x2 in enumerate(ds.coords['x2']):
        args = dict(x1=ix1, x2=ix2)
        a = ds['A'][args]
        b = ds['B'][args]
        c = func(a.values, b.values)
        ds['C'][args] = c

通过在数据集中初始化一个新数组并在其他维度上使用for循环

我对pandas不是很在行,但是对于其他数据类型,一个通用的解决方案也是使用理解,并去掉嵌套循环和初始化步骤

required_shape = (len(ds.coords['x1']), 
                  len(ds.coords['x2']),
                  len(ds.coords['x3']))

if 'C' not in ds:
    ds.update({'C': (['x1', 'x2', 'x3'], np.zeros(required_shape))})

for ix1, x1 in enumerate(ds.coords['x1']):
    for ix2, x2 in enumerate(ds.coords['x2']):
        args = dict(x1=ix1, x2=ix2)
        a = ds['A'][args]
        b = ds['B'][args]
        c = func(a.values, b.values)
        ds['C'][args] = c
required_shape = (len(ds.coords['x1']), 
                  len(ds.coords['x2']),
                  len(ds.coords['x3']))

ds['C'] = (['x1', 'x2', 'x3'], np.array([
    func(ds['A'][args].values, ds['B'][args].values)
    for ix1, x1 in enumerate(ds.coords['x1'])
    for ix2, x2 in enumerate(ds.coords['x2'])
    for args in (dict(x1=ix1, x2=ix2),)]).reshape(required_shape))
编辑:顺便说一句

required_shape = (len(ds.coords['x1']), 
                  len(ds.coords['x2']),
                  len(ds.coords['x3']))

if 'C' not in ds:
    ds.update({'C': (['x1', 'x2', 'x3'], np.zeros(required_shape))})

for ix1, x1 in enumerate(ds.coords['x1']):
    for ix2, x2 in enumerate(ds.coords['x2']):
        args = dict(x1=ix1, x2=ix2)
        a = ds['A'][args]
        b = ds['B'][args]
        c = func(a.values, b.values)
        ds['C'][args] = c
ds['C'] = func(ds['A'], ds['B'])
对于一个简单的函数,如:

required_shape = (len(ds.coords['x1']), 
                  len(ds.coords['x2']),
                  len(ds.coords['x3']))

if 'C' not in ds:
    ds.update({'C': (['x1', 'x2', 'x3'], np.zeros(required_shape))})

for ix1, x1 in enumerate(ds.coords['x1']):
    for ix2, x2 in enumerate(ds.coords['x2']):
        args = dict(x1=ix1, x2=ix2)
        a = ds['A'][args]
        b = ds['B'][args]
        c = func(a.values, b.values)
        ds['C'][args] = c
def func(a, b):
    return a + b