【问题标题】:Apply scipy.stats.percentileofscore to xarray resample reduce function将 scipy.stats.percentileofscore 应用于 xarray 重采样减少函数
【发布时间】:2020-03-11 08:24:57
【问题描述】:

我有以下名为 foo 的 xarray DataArray。

<xarray.DataArray (time: 4, lat: 3, lon: 2)>
array([[[0.061686, 0.434164],
        [0.642003, 0.78744 ],
        [0.068701, 0.526546]],

       [[0.53612 , 0.549919],
        [0.172044, 0.118106],
        [0.381638, 0.736584]],

       [[0.688589, 0.173351],
        [0.03593 , 0.833743],
        [0.667719, 0.890957]],

       [[0.712785, 0.04725 ],
        [0.132689, 0.938043],
        [0.681481, 0.67986 ]]])
Coordinates:
  * time     (time) datetime64[ns] 2000-01-01 2000-01-02 2000-01-03 2000-01-04
  * lat      (lat) <U2 'IA' 'IL' 'IN'
  * lon      (lon) <U2 '00' '22'

在进行 48 小时重采样时,我需要沿 time 维度应用 scipy.stats.percentileofscore 函数。

from scipy import stats
foo.resample(time='48H').reduce(stats.percentileofscore, dim='time', score=0.1)

我收到以下错误:

\variable.py", line 1354, in reduce
    axis=axis, **kwargs)
TypeError: percentileofscore() got an unexpected keyword argument 'axis'

【问题讨论】:

    标签: numpy scipy python-xarray


    【解决方案1】:

    复制数据:

    import xarray as xa
    
    array = np.array([[[0.061686, 0.434164],
            [0.642003, 0.78744 ],
            [0.068701, 0.526546]],
    
           [[0.53612 , 0.549919],
            [0.172044, 0.118106],
            [0.381638, 0.736584]],
    
           [[0.688589, 0.173351],
            [0.03593 , 0.833743],
            [0.667719, 0.890957]],
    
           [[0.712785, 0.04725 ],
            [0.132689, 0.938043],
            [0.681481, 0.67986 ]]])
    
    lat = ['IA','IL','IN']
    lon = ['00','22']
    
    times = pd.date_range('2000-01-01', periods=4, freq='H') #Hours
    
    foo = xr.DataArray(array, coords=[times, lat, lon], dims=['time', 'lat', 'lon'])
    

    你需要的功能:

    from scipy import stats
    import numpy as np
    
    def func(x, axis, score):
        out = np.apply_along_axis(stats.percentileofscore, axis, x, *[score])
        return out
    
    res = foo.resample(time='2H').reduce(func, **{'score':0.2}) #Each 2 hours
    

    输出:

    <xarray.DataArray (time: 2, lat: 3, lon: 2)>
    array([[[ 50.,   0.],
            [ 50.,  50.],
            [ 50.,   0.]],
    
           [[  0., 100.],
            [100.,   0.],
            [  0.,   0.]]])
    Coordinates:
      * time     (time) datetime64[ns] 2000-01-01 2000-01-01T02:00:00
      * lat      (lat) <U2 'IA' 'IL' 'IN'
      * lon      (lon) <U2 '00' '22'
    

    说明

    函数期望什么及其输出:

    def func2(x, axis): #Expect a function with axis argument (error reason)
        print(x) #to see the output that our function receive as input
        return x  #not relevant
    
    foo.resample(time='2H').reduce(func2)
    
    #Input of our func2 (two new arrays with shape (2,3,2))
    a = np.array([[[0.061686, 0.434164],
      [0.642003, 0.78744 ],
      [0.068701, 0.526546]],
    
     [[0.53612,  0.549919],
      [0.172044, 0.118106],
      [0.381638, 0.736584]]])
    
    b = np.array([[[0.688589, 0.173351],
      [0.03593,  0.833743],
      [0.667719, 0.890957]],
    
     [[0.712785, 0.04725 ],
      [0.132689, 0.938043],
      [0.681481, 0.67986 ]]])
    

    所以,你正在做的是:

    stats.percentileofscore(a, score=0.2) #200  #Reduce over lon and lat
    stats.percentileofscore(b, score=0.2) #200  #This raise another error
    

    这就是为什么您需要一个通过轴操作的函数(例如np.mean(a, axis=None, ...)np.apply_along_axis 帮助我们完成这项任务的原因:

    #reduce through hours 1-2 and hours 3-4 (axis=0)
    np.apply_along_axis(stats.percentileofscore, 0, a, **{'score':0.2}) 
    np.apply_along_axis(stats.percentileofscore, 0, b, **{'score':0.2}) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-16
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 2017-09-30
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      相关资源
      最近更新 更多