Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在函数上使用groupby_Python_Pandas_Statistics - Fatal编程技术网

Python 在函数上使用groupby

Python 在函数上使用groupby,python,pandas,statistics,Python,Pandas,Statistics,我有一个计算x和y变量斜率(theil sen斜率)的代码,我想在基于组的值列表上运行它。我的文件如下所示: station\u id年份总和 210018 1917 329.946 210018 1918 442.214 210018 1919 562.864 210018 1920 396.748 210018 1921 604.266 210019 1917 400.946 210019 1918

我有一个计算x和y变量斜率(theil sen斜率)的代码,我想在基于组的值列表上运行它。我的文件如下所示:

station\u id年份总和
210018     1917    329.946
210018     1918    442.214
210018     1919    562.864
210018     1920    396.748
210018     1921    604.266
210019     1917    400.946
210019     1918    442.214
210019     1919    600.864
210019     1920    250.748
2100191921100.266

我的输出应该是:

210018: -117189.92, 61.29
210019: 164382, -85.45
我使用的代码是:

def theil_sen(x,y):
    n   = len(x)
    ord = numpy.argsort(x)
    xs  = x[ord]
    ys  = y[ord]
    vec1 = numpy.zeros( (n,n) )
    for ii in range(n):
        for jj in range(n):
            vec1[ii,jj] = ys[ii]-ys[jj]
    vec2 = numpy.zeros( (n,n) )
    for ii in range(n):
        for jj in range(n):
            vec2[ii,jj] = xs[ii]-xs[jj]
    v1    = vec1[vec2>0]    
    v2    = vec2[vec2>0]     
    slope = numpy.median( v1/v2 )
    coef  = numpy.zeros( (2,1) ) 
    b_0   = numpy.median(y)-slope*numpy.median(x)
    b_1   = slope
    res   = y-b_1*x-b_0 # residuals 

    return (b_0,b_1,res)

stat=df.groupby(['station_id']).apply(lambda x: theil_sen(x['year'], x['Sum']))

print stat
因此,
year
是我的x变量,
Sum
是我的y变量。对于站点210018,代码正确执行,但对于210019,代码返回nan。任何帮助都将不胜感激。

numpy.argsort(x)
与pandas系列进行折腾。在第一个组之后,它不会像预期的那样工作,因为索引不再从0到n。改为使用
x,y
Numpy数组

这很有效

def theil_sen(x,y):
    x = x.values
    y = y.values
    n   = len(x)
    ord = numpy.argsort(x)
    xs  = x[ord]
    ys  = y[ord]
    vec1 = numpy.zeros( (n,n) )
    for ii in range(n):
        for jj in range(n):
            vec1[ii,jj] = ys[ii]-ys[jj]
    vec2 = numpy.zeros( (n,n) )
    for ii in range(n):
        for jj in range(n):
            vec2[ii,jj] = xs[ii]-xs[jj]
    v1    = vec1[vec2>0]    
    v2    = vec2[vec2>0]     
    slope = numpy.median( v1/v2 )
    coef  = numpy.zeros( (2,1) ) 
    b_0   = numpy.median(y)-slope*numpy.median(x)
    b_1   = slope
    res   = y-b_1*x-b_0 # residuals 

    return (b_0,b_1,res)

stat=df.groupby(['station_id']).apply(lambda x: theil_sen(x['year'], x['Sum']))

print stat


station_id
210018        (-117189.927333, 61.2986666667, [10.3293333333...
210019        (164382.3745, -85.4515, [-170.903, -44.1835, 1...
dtype: object
现有功能的唯一补充是这两条线

x = x.values
y = y.values
现在,让我们看看当您在series对象的第一个组之后应用np.argsort()时发生了什么错误。让我们取第二组值。那是-

In [70]: x
Out[70]:
5    1917
6    1918
7    1919
8    1920
9    1921
Name: year, dtype: int64

In [71]: numpy.argsort(x)
Out[71]:
5    0
6    1
7    2
8    3
9    4
Name: year, dtype: int64

In [72]: x[numpy.argsort(x)]
Out[72]:
year
0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
Name: year, dtype: float64

由于
ord
总是来自
[0-n]
,后面的组的
x[ord]
显然返回
NaN
值。

scipy-theil斜率中有一个错误,它不能给出正确的结果。如果有人知道如何通过编写循环来实现这一点,我也会很高兴,它不必与groupby necessarilyYou可能要删除for循环(矢量化)。FWIW我在运行这段代码时看到一个警告,表示您正在使用空数组的平均值(可能这就是nan的原因)。调试这个(IMO)的最简单方法是粘贴
importPDB;pdb.将_trace()
设置为函数的第一行,在有问题的组中调用它,然后逐行遍历每一行,直到看到nan发生的位置。我对此进行了几分钟的讨论。我认为v1/v2对于某些数据值是空的,这与Andy的建议一致。此外,coef在代码中似乎没有任何用途,仅供参考。无论如何,您的groupby/apply可能还可以,只是函数本身有问题。