Python 在函数上使用groupby
我有一个计算x和y变量斜率(theil sen斜率)的代码,我想在基于组的值列表上运行它。我的文件如下所示: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
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可能还可以,只是函数本身有问题。