【发布时间】:2014-10-17 16:20:20
【问题描述】:
我有多个时间序列,其中观察值作为行(由时间戳索引,n > 5000)和变量作为列(n = 419)。我在时间序列中选择 N 百分比的包含,然后调用 groupby 以按年分组。我想要的是平均值、标准差,然后是每年的 95% 置信区间。使用下面的代码,我可以很容易地得到 mean 和 std,但我需要调用一个单独的引导函数来获得每年和每个组的 95% CI:
这是分组数据的外观:(2013 年有 86 行,28 列,数据始于 1970 年代)。我需要为分组中的每一年分组的每一列使用“bootsrap”。
for year, group in grouped:
print year
print group
2013
101 102 103 104 105 109
2013-04-02 3162.84 4136.02 77124.56 0.00 973.18 9731.81
2013-04-04 1033.81 5464.44 87283.30 3692.19 4282.94 295.37
2013-04-04 640.75 4164.87 131033.14 2563.00 1121.31 961.12
2013-04-10 246.87 4196.84 88380.57 4443.72 493.75 1234.37
2013-04-13 0.00 8300.49 114291.42 10003.16 212.83 6385.00
` 以下是我的 groupby 和 bootstrap 函数:
def gbY_20pct(nm): # sort into 20% timeseries inclusion, groupby year, take mean for year
nm1=nm.replace('0', np.nan) # remove 0 for logical count
coun=nm1.count(axis=0,numeric_only=True)
pct=(coun/len(nm1)) *100
pCount=pct.loc[pct >= 20]
nm1=nm.loc[:, pCount.index]
grouped = nm1.groupby(nm1.index.map(lambda x: x.year))
yrly=grouped.mean().astype(int)
yrly_coun=grouped.count().astype(int)
yrly_std=grouped.std().astype(int)
yrly_max=grouped.max().astype(int)
yrM1=yrly.join(yrly_std, lsuffix=' mean', rsuffix=' std', how='outer')
yrM2=yrly_max.join(yrly_coun, lsuffix=' max', rsuffix=' count', how='outer')
data=yrM1.join(yrM2, how='outer')
return data
`
import numpy as np
import numpy.random as npr
def bootstrap(data, num_samples, statistic, alpha):
"""Returns bootstrap estimate of 100.0*(1-alpha) CI for statistic."""
n = len(data)
idx = npr.randint(0, n, (num_samples, n))
samples = data[idx]
stat = np.sort(statistic(samples, 1))
return (stat[int((alpha/2.0)*num_samples)],
stat[int((1-alpha/2.0)*num_samples)])
为了测试代码,我是手动调用的(分组已经定义,函数没有关闭)
from bootstrap import bootstrap
low, high = bootstrap(grouped, 100000, np.mean, 0.05)
Traceback (most recent call last):
File "<ipython-input-49-cd362c7908d1>", line 1, in <module>
low, high = bootstrap(grouped, 100000, np.mean, 0.05)
File "bootstrap.py", line 14, in bootstrap
File "C:\Users\ryan.morse\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\groupby.py", line 2991, in __getitem__
bad_keys = list(set(key).difference(self.obj.columns))
TypeError: unhashable type: 'numpy.ndarray'
问题来自samples = data[idx] 行。我怀疑我需要比在引导程序中对数据字段使用“分组”更具体,但我不确定如何做到这一点。我需要将其作为 lambda 函数应用吗?或者也许有一个 for 循环?任何建议将不胜感激。
查看此页面后:Pandas, compute many means with bootstrap confidence intervals for plotting 并尝试了 scikit 引导函数 https://scikits.appspot.com/bootstrap,我测试了上面定义的函数,发现它的速度要快得多,结果可比。
编辑:
我认为这样的事情可能会起作用,但我仍然无法获得正确的语法:
groups=dict(list(grouped)) # this allows me to visualize the data and call values
for key, value in groups.iteritems():
low_i, high_i = bootstrap(groups.values(), 100000, np.mean, 0.05)
Traceback (most recent call last):
File "<ipython-input-36-7a8e261d656e>", line 2, in <module>
low_i, high_i=bootstrap(groups.values(), 10000, np.mean, 0.05)
File "<ipython-input-15-3ce4acd651dc>", line 7, in bootstrap
samples = data[idx]
TypeError: only integer arrays with one element can be converted to an index
我不确定如何为引导函数调用“数据”,以及如何迭代所有年份并在所有年份中保持低位和高位(在同一个数据帧中或在 2 个单独的数据帧中)。
任何帮助将不胜感激...
编辑 2 我可以很容易地使用 lambda 函数,但是我似乎无法获得正确的输出:
for col, group in nm1.groupby(nm1.index.year):
lo,hi=bootstrap(group,1000, np.mean, 0.05)
lo
Out[117]:
array([ 0.05713616, 0.30724739, 0.39592714, 0.55113183, 0.68623155,
0.69493923, 0.73513661, 0.84086099, 0.85882618, 0.86698939,
0.99399694, 1.04415927, 1.06553914, 1.11306698, 1.15344871,
1.27943327, 1.43275895, 1.81076036, 2.21647657, 2.37724615,
2.39004626, 2.43154256, 2.89940325, 3.02234954, 3.30773642,
3.96535146, 3.98973744, 4.38873853])
hi
Out[118]:
array([ 0.20584822, 0.38832222, 0.42140066, 0.48615202, 0.59686031,
0.67388397, 0.84269082, 0.84532503, 0.87078368, 0.9033272 ,
0.90765817, 0.97523759, 0.99186096, 1.01668772, 1.06681722,
1.18205259, 1.38524423, 1.79908484, 2.22314773, 2.33789105,
2.5521743 , 2.64242269, 2.88851233, 2.94387756, 3.44294791,
3.63914938, 3.99185026, 4.36450246])
如果这行得通,我将在 33 年的每一年中对 28 列中的每一列都有 lo 和 hi,而不是我有一个似乎没有任何实际价值的有序数字数组......这是一个yrly 的 sn-p 包含每年的对数转换 groupby 均值,与上述数组不同,自举 CI 应该接近这些数字。
101 102 103 104 105 109 135
1978 3.416638 3.701268 3.828442 2.911944 2.687491 2.076515 1.232035
1979 2.710939 3.172061 4.234109 1.666818 3.390646 1.355179 3.003813
1980 2.652617 2.375495 3.316380 1.101594 2.220028 1.195449 1.998862
1981 3.363424 3.485015 3.441784 2.242618 2.256745 1.719140 1.150454
1982 2.791865 2.019883 4.093960 1.038226 2.106627 1.180935 2.456144
1983 2.597307 2.213450 4.458691 1.274352 2.820910 1.705242 3.452762
1984 3.042197 4.023952 3.816964 2.499883 2.445258 1.769485 1.690180
1985 2.669850 2.162608 3.600731 1.400102 1.845218 1.234235 2.517108
1986 3.597527 2.763436 2.790792 1.410343 2.116275 1.042812 1.528532
【问题讨论】:
标签: python pandas group-by statistics-bootstrap